0

您好我正在尝试在不使用解析 SDK 的情况下使用 Twitter 的 REST API。我从 parse twitter 类中获得了访问令牌和访问令牌秘密,谁能告诉我我做错了什么。

我正在使用 twitter 的 REST api 1.1。

    private void usingNetwork() {
    // TODO Auto-generated method stub
    new AsyncTask<Void, Void, String>() {

        @Override
        protected String doInBackground(Void... params) {
            // TODO Auto-generated method stub

            try {
                URL ur = new URL(
                                        "https://api.twitter.com/1.1/statuses/user_timeline.json?  screen_name=suresh_bora&include_entities=true");
                HttpURLConnection conn = (HttpURLConnection) ur
                        .openConnection();
                conn.addRequestProperty("Content-Type",
                        "application/x-www-form-urlencoded");
                conn.addRequestProperty(
                        "Authorization",
                        "OAuth oauth_consumer_key="
                                + ParseTwitterUtils.getTwitter()
                                        .getConsumerKey()
                                + ",oauth_token="
                                + ParseTwitterUtils.getTwitter()
                                        .getAuthToken()
                                + ",oauth_nonce=kYjzVBB8Y0ZFdfdfabxSWbWovY3uYSQ2pTgmZeNu2VS4cg," +
                                "oauth_signature_method=HMAC-SHA1," +
                                "oauth_timestamp="+ new Timestamp(date.getSeconds()) +
                                ",oauth_version=1.0,"+
                                "oauth_signature="+ParseTwitterUtils.getTwitter().getAuthTokenSecret()+"");
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.setRequestMethod("GET");

                readStream(conn.getInputStream());
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;

        }

        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
        }
    }.execute();
}

}

4

2 回答 2

2

这对我有帮助:

SSL 绝对需要。 这种身份验证方式只有在使用 SSL 时才安全。因此,所有请求(获取和使用令牌)都必须使用 HTTPS 端点”((c) https://dev.twitter.com/docs /auth/application-only-auth )

所以你必须使用 HttpsURLConnection 而不是 Http。之后检查你是否获得了令牌,它看起来像“AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA”。

这是一个例子:

 private final static String getTokenURL = "https://api.twitter.com/oauth2/token";
 private static String bearerToken;

/**
 * @param args
 */
public static void main(String[] args) {

    // encodeKeys(APIKEY, APISECRET);

    new Thread(new Runnable() {

        @Override
        public void run() {
            try {

                bearerToken = requestBearerToken(getTokenURL);
                fetchTimelineTweet(twitURL);

            } catch (IOException e) {
                System.out.println("IOException e");
                e.printStackTrace();
            }
        }
    }).start();

}

// Encodes the consumer key and secret to create the basic authorization key
private static String encodeKeys(String consumerKey, String consumerSecret) {
    try {
        String encodedConsumerKey = URLEncoder.encode(consumerKey, "UTF-8");
        String encodedConsumerSecret = URLEncoder.encode(consumerSecret,
                "UTF-8");

        String fullKey = encodedConsumerKey + ":" + encodedConsumerSecret;
        byte[] encodedBytes = Base64.encodeBase64(fullKey.getBytes());

        return new String(encodedBytes);
    } catch (UnsupportedEncodingException e) {
        return new String();
    }
}

// Constructs the request for requesting a bearer token and returns that
// token as a string
private static String requestBearerToken(String endPointUrl)
        throws IOException {
    HttpsURLConnection connection = null;
    String encodedCredentials = encodeKeys(APIKEY, APISECRET);

    System.out.println("encodedCredentials "+encodedCredentials);
    try {
        URL url = new URL(endPointUrl);
        connection = (HttpsURLConnection) url.openConnection();
        System.out.println(connection);
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Host", "api.twitter.com");
        connection.setRequestProperty("User-Agent", "anyApplication");
        connection.setRequestProperty("Authorization", "Basic "
                + encodedCredentials);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        connection.setRequestProperty("Content-Length", "29");
        connection.setUseCaches(false);

        writeRequest(connection, "grant_type=client_credentials");

        // Parse the JSON response into a JSON mapped object to fetch fields
        // from.
        JSONObject obj = (JSONObject) JSONValue.parse(readResponse(connection));

        if (obj != null) {
            String tokenType = (String) obj.get("token_type");
            String token = (String) obj.get("access_token");

            return ((tokenType.equals("bearer")) && (token != null)) ? token
                    : "";
        }
        return new String();
    } catch (MalformedURLException e) {
        throw new IOException("Invalid endpoint URL specified.", e);
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }
}

// Fetches the first tweet from a given user's timeline
private static String fetchTimelineTweet(String endPointUrl)
        throws IOException {
    HttpsURLConnection connection = null;

    try {
        URL url = new URL(endPointUrl);
        connection = (HttpsURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Host", "api.twitter.com");
        connection.setRequestProperty("User-Agent", "anyApplication");
         connection.setRequestProperty("Authorization", "Bearer " +  bearerToken);
        connection.setUseCaches(false);

        // Parse the JSON response into a JSON mapped object to fetch fields
        // from.
        JSONArray obj = (JSONArray) JSONValue.parse(readResponse(connection));
        System.out.println("JSON obj = "+obj);

        if (obj != null) {
            String tweet = ((JSONObject) obj.get(0)).get("text").toString();
            System.out.println(tweet);
            return (tweet != null) ? tweet : "";
        }
        return new String();
    } catch (MalformedURLException e) {
        throw new IOException("Invalid endpoint URL specified.", e);
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }
}

// Writes a request to a connection
private static boolean writeRequest(HttpURLConnection connection,
        String textBody) {
    try {
        BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(
                connection.getOutputStream()));
        wr.write(textBody);
        wr.flush();
        wr.close();

        return true;
    } catch (IOException e) {
        return false;
    }
}

// Reads a response for a given connection and returns it as a string.
private static String readResponse(HttpURLConnection connection) {
    try {
        StringBuilder str = new StringBuilder();

        BufferedReader br = new BufferedReader(new InputStreamReader(
                connection.getInputStream()));
        String line = "";
        while ((line = br.readLine()) != null) {
            str.append(line + System.getProperty("line.separator"));
        }
        return str.toString();
    } catch (IOException e) {
        return new String();
    }
}

}

于 2013-06-27T17:29:22.237 回答
0

除此之外,您可以在上面找到 Defuera 发布的代码示例以及更多信息: http: //www.coderslexicon.com/demo-of-twitter-application-only-oauth-authentication-using-java/

我做错的是将不记名令牌编码为base 64,你不需要这样做。

一旦你有了不记名令牌,你就可以打开另一个到 Twitter 的 HttpsUrlConnection 并处理响应。

我个人所做的只是取回一个对象并将其作为 json 返回到前端。

如果您尝试转换为特定的 json 类型,例如,如果您使用的是 org.simple.json,Twitter 将返回 JSON 数组或 JSON 对象,具体取决于您调用的 REST URL。因此,如果您尝试将其转换为 JSONObject 或 JSONArray,如果您选择了错误的类型,它将引发异常:

private Object requestTwitterApi(String endPointUrl, Map<String, String[]> params)
        throws IOException {

    HttpsURLConnection connection = null;

    // Generate query
    String query = generateQueryUrl(params);
    // Append query to URL
    endPointUrl += query;
    // endPointUrl is now: https://api.twitter.com/1.1/search/tweets.json?q=%40twitterapi for example

    try {
        URL url = new URL(endPointUrl);
        connection = (HttpsURLConnection) url.openConnection();
        LOGGER.debug("TwitterApiUrl: " + connection);
        connection.setDoOutput(true);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Host", "api.twitter.com");
        connection.setRequestProperty("User-Agent", "anyApplication");
        connection.setRequestProperty("Authorization", "Bearer " + bearerToken); // bearer token is exactly what was returned from Twitter
        connection.setUseCaches(false);

        // Parse the JSON response into a JSON mapped object
        JSONParser parser = new JSONParser();
        Object obj = null;
        try {
            obj = parser.parse(readResponse(connection));
        } catch (ParseException e) {
            LOGGER.debug("Exception parsing JSON from Twitter");
            e.printStackTrace();
        }
        // then just return the object and I use struts-json-plugin to convert to json and return to frontend. This will allow you to return JSON objects or arrays without issue
        return obj != null ? obj : "";

    } catch (MalformedURLException e) {
        LOGGER.error("Invalid endpoint URL specified : " + e);
        throw new IOException("Invalid endpoint URL specified.", e);
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }
}

我希望这对某人有所帮助,这最终花了我一整天的时间来使用 Twitter API ......(我们正在做自定义分析)相比之下,Facebook 花了 30 分钟。

于 2015-01-28T08:57:24.293 回答