【问题标题】:Simplest Java example retrieving user_timeline with twitter API version 1.1使用 twitter API 版本 1.1 检索 user_timeline 的最简单 Java 示例
【发布时间】:2012-11-03 10:23:55
【问题描述】:

我正在寻找一个使用 Twitter 1.1 API 的简单 Java 示例,但找不到。使用此处发布的 PHP 示例:Simplest PHP example for retrieving user_timeline with Twitter API version 1.1 和其他一些 Stackoverflow 帖子,我能够提出以下工作示例。

public void testUserTimelineWithAuthSample() throws Exception {
    //This will read the timeline of your account.
    String method = "GET";
    String url = "https://api.twitter.com/1.1/statuses/user_timeline.json";

    String oAuthConsumerKey = "Your value here.";
    String oAuthConsumerSecret = "Your value here."; //<--- DO NOT SHARE THIS VALUE

    String oAuthAccessToken = "Your value here.";
    String oAuthAccessTokenSecret = "Your value here."; //<--- DO NOT SHARE THIS VALUE

    String oAuthNonce = String.valueOf(System.currentTimeMillis());
    String oAuthSignatureMethod = "HMAC-SHA1";
    String oAuthTimestamp = time();
    String oAuthVersion = "1.0";

    String signatureBaseString1 = method;
    String signatureBaseString2 = url;
    String signatureBaseString3Templ = "oauth_consumer_key=%s&oauth_nonce=%s&oauth_signature_method=%s&oauth_timestamp=%s&oauth_token=%s&oauth_version=%s";
    String signatureBaseString3 = String.format(signatureBaseString3Templ,
                                                    oAuthConsumerKey, 
                                                    oAuthNonce,
                                                    oAuthSignatureMethod,
                                                    oAuthTimestamp,
                                                    oAuthAccessToken,
                                                    oAuthVersion);

    String signatureBaseStringTemplate = "%s&%s&%s";
    String signatureBaseString =  String.format(signatureBaseStringTemplate, 
                                                                URLEncoder.encode(signatureBaseString1, "UTF-8"), 
                                                                URLEncoder.encode(signatureBaseString2, "UTF-8"),
                                                                URLEncoder.encode(signatureBaseString3, "UTF-8"));

    System.out.println("signatureBaseString: "+signatureBaseString);

    String compositeKey = URLEncoder.encode(oAuthConsumerSecret, "UTF-8") + "&" + URLEncoder.encode(oAuthAccessTokenSecret, "UTF-8");

    String oAuthSignature =  computeSignature(signatureBaseString, compositeKey);
    System.out.println("oAuthSignature       : "+oAuthSignature);

    String oAuthSignatureEncoded = URLEncoder.encode(oAuthSignature, "UTF-8");
    System.out.println("oAuthSignatureEncoded: "+oAuthSignatureEncoded);

    String authorizationHeaderValueTempl = "OAuth oauth_consumer_key=\"%s\", oauth_nonce=\"%s\", oauth_signature=\"%s\", oauth_signature_method=\"%s\", oauth_timestamp=\"%s\", oauth_token=\"%s\", oauth_version=\"%s\"";

    String authorizationHeaderValue = String.format(authorizationHeaderValueTempl,
                                                        oAuthConsumerKey,
                                                        oAuthNonce,
                                                        oAuthSignatureEncoded,
                                                        oAuthSignatureMethod,
                                                        oAuthTimestamp,
                                                        oAuthAccessToken,
                                                        oAuthVersion);
    System.out.println("authorizationHeaderValue: "+authorizationHeaderValue);


    System.out.println("url: "+url);
    System.out.println("authorizationHeaderValue:"+authorizationHeaderValue);

    GetMethod getMethod = new GetMethod(url);
    getMethod.addRequestHeader("Authorization", authorizationHeaderValue);
    HttpClient cli = new HttpClient();
    int status = cli.executeMethod(getMethod);
    System.out.println("Status:"+status);

    long responseContentLength = getMethod.getResponseContentLength();
    System.out.println("responseContentLength:"+responseContentLength);

    String response = getMethod.getResponseBodyAsString();  
    System.out.println("response: "+response);
}


private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException, Exception 
{
    SecretKey secretKey = null;

    byte[] keyBytes = keyString.getBytes();
    secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");

    Mac mac = Mac.getInstance("HmacSHA1");

    mac.init(secretKey);

    byte[] text = baseString.getBytes();

    return new String(Base64.encodeBase64(mac.doFinal(text))).trim();
}

private String time() {
    long millis = System.currentTimeMillis();
    long secs = millis / 1000;
    return String.valueOf( secs );
}

但是,如果我在 url 中添加参数,例如:

String url = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=2";

我明白了:

响应:{"errors":[{"message":"Could not authenticate you","code":32}]}

知道这是哪里出错了吗?

【问题讨论】:

    标签: java twitter twitter-oauth


    【解决方案1】:

    这对于带有新 Twitter API 1.1 的 Timeline 非常有效

    1) 在http://twitter4j.org/en/ 下载 twitter4j-core-3.0.3.jar 2)尝试使用此代码:

    private static final String TWITTER_CONSUMER_KEY = "xxxxxxxxxxxxxxxxxx";
    private static final String TWITTER_SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    private static final String TWITTER_ACCESS_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxx";
    private static final String TWITTER_ACCESS_TOKEN_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxxx";
    
    ConfigurationBuilder cb = new ConfigurationBuilder();
    cb.setDebugEnabled(true)
        .setOAuthConsumerKey(TWITTER_CONSUMER_KEY)
        .setOAuthConsumerSecret(TWITTER_SECRET_KEY)
        .setOAuthAccessToken(TWITTER_ACCESS_TOKEN)
        .setOAuthAccessTokenSecret(TWITTER_ACCESS_TOKEN_SECRET);
    TwitterFactory tf = new TwitterFactory(cb.build());
    Twitter twitter = tf.getInstance();
    try {
        Query query = new Query("MrEdPanama");
        QueryResult result;
        do {
            result = twitter.search(query);
            List<Status> tweets = result.getTweets();
            for (Status tweet : tweets) {
                System.out.println("@" + tweet.getUser().getScreenName() + " - " + tweet.getText());
            }
        } while ((query = result.nextQuery()) != null);
        System.exit(0);
    } catch (TwitterException te) {
        te.printStackTrace();
        System.out.println("Failed to search tweets: " + te.getMessage());
        System.exit(-1);
    }
    

    【讨论】:

      【解决方案2】:

      oauth_nonce 有误。它是一个以 64 为基数编码的随机 32 字节字符串。

      你可以像这样构建它们:

      public String generateNonce() {
          Random gen = new Random(System.currentTimeMillis());
          StringBuilder nonceBuilder = new StringBuilder("");
          String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
          int baseLength = base.length();
      
          // Taking random word characters
          for (int i = 0; i < 32; ++i) {
              int position = gen.nextInt(baseLength);
              nonceBuilder.append(base.charAt(position));
          }
      
          String nonce = toBase64(nonceBuilder.toString());
      
          return nonce;
      }
      
      // In your code :
      String oAuthNonce = generateNonce();
      

      String toBase64(String); 是一种使用 Base 64 编码字符串的方法。

      【讨论】:

        【解决方案3】:

        这是一个使用参数的 Twitter 1.1 API 示例。该问题与随机数无关。它是签名基础字符串。将 signatureBaseString 视为由 & 符号 (METHOD&URL&PARAMS) 分隔的 3 部分字符串。 api 参数不包含在 signatureBaseString 的第二部分中,它们将(与其他 6 个安全参数一起)包含在 signatureBaseString 的最后部分中(另外,这些参数必须按字母顺序排列)。

            public void testUserTimelineWithParams() throws Exception {
            //This will read the timeline of the 'twitterapi' account.
        
            String method = "GET";
            String url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
            List<NameValuePair> urlParams = new ArrayList<NameValuePair>();
            urlParams.add( new NameValuePair("screen_name","twitterapi") );
            urlParams.add( new NameValuePair("count", "10") );
        
            String oAuthConsumerKey = "Your value";
            String oAuthConsumerSecret = "Your value"; //<--- DO NOT SHARE THIS VALUE
        
            String oAuthAccessToken = "Your value";
            String oAuthAccessTokenSecret = "Your value"; //<--DO NOT SHARE THIS VALUE
        
            String oAuthNonce = String.valueOf(System.currentTimeMillis());
            String oAuthSignatureMethod = "HMAC-SHA1";
            String oAuthTimestamp = time();
            String oAuthVersion = "1.0";
        
            String signatureBaseString1 = method;
            String signatureBaseString2 = url;
        
            List<NameValuePair> allParams = new ArrayList<NameValuePair>();
            allParams.add(new NameValuePair("oauth_consumer_key", oAuthConsumerKey));
            allParams.add(new NameValuePair("oauth_nonce", oAuthNonce));
            allParams.add(new NameValuePair("oauth_signature_method", oAuthSignatureMethod));
            allParams.add(new NameValuePair("oauth_timestamp", oAuthTimestamp));
            allParams.add(new NameValuePair("oauth_token", oAuthAccessToken));
            allParams.add(new NameValuePair("oauth_version", oAuthVersion));
            allParams.addAll(urlParams);
        
            Collections.sort(allParams, new NvpComparator());
        
            StringBuffer signatureBaseString3 = new StringBuffer();
            for(int i=0;i<allParams.size();i++)
            {
                NameValuePair nvp = allParams.get(i);
                if (i>0) {
                    signatureBaseString3.append("&");
                }
                signatureBaseString3.append(nvp.getName() + "=" + nvp.getValue());
            }
        
            String signatureBaseStringTemplate = "%s&%s&%s";
            String signatureBaseString =  String.format(signatureBaseStringTemplate, 
                                                                        URLEncoder.encode(signatureBaseString1, "UTF-8"), 
                                                                        URLEncoder.encode(signatureBaseString2, "UTF-8"),
                                                                        URLEncoder.encode(signatureBaseString3.toString(), "UTF-8"));
        
            System.out.println("signatureBaseString: "+signatureBaseString);
        
            String compositeKey = URLEncoder.encode(oAuthConsumerSecret, "UTF-8") + "&" + URLEncoder.encode(oAuthAccessTokenSecret, "UTF-8");
        
            String oAuthSignature =  computeSignature(signatureBaseString, compositeKey);
            System.out.println("oAuthSignature       : "+oAuthSignature);
        
            String oAuthSignatureEncoded = URLEncoder.encode(oAuthSignature, "UTF-8");
            System.out.println("oAuthSignatureEncoded: "+oAuthSignatureEncoded);
        
            String authorizationHeaderValueTempl = "OAuth oauth_consumer_key=\"%s\", oauth_nonce=\"%s\", oauth_signature=\"%s\", oauth_signature_method=\"%s\", oauth_timestamp=\"%s\", oauth_token=\"%s\", oauth_version=\"%s\"";
        
            String authorizationHeaderValue = String.format(authorizationHeaderValueTempl,
                                                                oAuthConsumerKey,
                                                                oAuthNonce,
                                                                oAuthSignatureEncoded,
                                                                oAuthSignatureMethod,
                                                                oAuthTimestamp,
                                                                oAuthAccessToken,
                                                                oAuthVersion);
            System.out.println("authorizationHeaderValue: "+authorizationHeaderValue);
        
            StringBuffer urlWithParams = new StringBuffer(url);
            for(int i=0;i<urlParams.size();i++) {
                if(i==0) 
                {
                    urlWithParams.append("?");
                }
                else
                {
                    urlWithParams.append("&");
                }
                NameValuePair urlParam = urlParams.get(i);
                urlWithParams.append(urlParam.getName() + "=" + urlParam.getValue());
            }
        
            System.out.println("urlWithParams: "+urlWithParams.toString());
            System.out.println("authorizationHeaderValue:"+authorizationHeaderValue);
        
            GetMethod getMethod = new GetMethod(urlWithParams.toString());
            getMethod.addRequestHeader("Authorization", authorizationHeaderValue);
        
            HttpClient cli = new HttpClient();
            int status = cli.executeMethod(getMethod);
            System.out.println("Status:"+status);
        
            long responseContentLength = getMethod.getResponseContentLength();
            System.out.println("responseContentLength:"+responseContentLength);
        
            String response = getMethod.getResponseBodyAsString();  
            System.out.println("response: "+response);
        }   
        
        private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException, Exception 
        {
            SecretKey secretKey = null;
        
            byte[] keyBytes = keyString.getBytes();
            secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");
        
            Mac mac = Mac.getInstance("HmacSHA1");
        
            mac.init(secretKey);
        
            byte[] text = baseString.getBytes();
        
            return new String(Base64.encodeBase64(mac.doFinal(text))).trim();
        }
        
        private String time() {
            long millis = System.currentTimeMillis();
            long secs = millis / 1000;
            return String.valueOf( secs );
        }
        

        NvpComparator 在哪里:

        public class NvpComparator implements Comparator<NameValuePair> {
        
        public int compare(NameValuePair arg0, NameValuePair arg1) {
            String name0 = arg0.getName();
            String name1 = arg1.getName();
            return name0.compareTo(name1);
        }
        

        }

        【讨论】:

          【解决方案4】:

          这是我使用 twitter4j lib 的解决方案

                      Twitter twitter = new TwitterFactory().getInstance();
          
                      AccessToken accessToken = new AccessToken(accessTokenStr, accessTokenSecretStr);
                      twitter.setOAuthConsumer(consumerKeyStr, consumerSecretStr);
                      twitter.setOAuthAccessToken(accessToken);
          
                      try {
                          Query query = new Query("#<HASHTAG TO SEARCH>");
                          QueryResult result;
                          result = twitter.search(query);
                          List<Status> tweets = result.getTweets();
                          for (Status tweet : tweets) {
                              System.out.println("@" + tweet.getUser().getScreenName() + " - " + tweet.getText());
                          }
                      }
                      catch (TwitterException te) {
                          te.printStackTrace();
                          System.out.println("Failed to search tweets: " + te.getMessage());
                          System.exit(-1);
                      }
          

          【讨论】:

            猜你喜欢
            • 2012-10-06
            • 2013-10-22
            • 2012-12-25
            • 2013-01-16
            • 1970-01-01
            • 2012-12-04
            • 1970-01-01
            • 2012-12-10
            • 2013-01-25
            相关资源
            最近更新 更多