乐者为王

Do one thing, and do it well.

构建支持OAuth的新浪微博桌面客户端

要使用OAuth,首先要去新浪微博注册一个自己的微博应用。注册之后,会得到微博应用的Consumer key和Consumer secret,都是一个字符串。之后就可以进行OAuth的认证过程了。

https://code.google.com/p/sina-weibo4j/ 下载新浪微博的Java SDK包,当然也可以在 http://open.weibo.com/wiki/index.php/SDK 下载。推荐使用前者,已经打好包了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Properties;
import java.util.PropertyResourceBundle;

import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.http.AccessToken;
import weibo4j.http.RequestToken;

public class UpdateStatus {
  private static final String ACCESS_SECRET = "access_secret";
  private static final String ACCESS_TOKEN = "access_token";
  private static final String FILE_NAME = "sina_token.properties";

  public static void main(String[] args) {
    // 在这里填写在应用申请中得到的App Key和App Secret
    System.setProperty("weibo4j.oauth.consumerKey", YOUR_CONSUMER_KEY);
    System.setProperty("weibo4j.oauth.consumerSecret", YOUR_CONSUMER_SECRET);

    Weibo weibo = new Weibo();

    try {
      // 读取存储起来的Access Token
      AccessToken accessToken = loadAccessToken();
      if (accessToken == null) {
        String backUrl = "http://zhubabo.appspot.com";

        // 请求Request Token(未授权令牌)
        RequestToken requestToken = weibo.getOAuthRequestToken(backUrl);
        System.out.println("Got request token...");
        System.out.println("Request token: " + requestToken.getToken());
        System.out.println("Request token secret: " + requestToken.getTokenSecret());

        // 将以下打印出的授权链接在浏览器中打开,完成应用授权,会自动跳转到
        // 指定的callback url,并将oauth_verifier一起返回
        System.out.println("Open the following url in a browser");
        System.out.println(" http://api.t.sina.com.cn/oauth/authorize?oauth_token=" + requestToken.getToken());

        // 输入上面得到的oauth_verifier的值,取得Access Token,这个Token是长期有效的
        System.out.println("please input verifier:");
        String verifier = readLine();
        accessToken = weibo.getOAuthAccessToken(
            requestToken.getToken(),
            requestToken.getTokenSecret(),
            verifier);

        // 将Access Token保存下来,以后就可以直接通过此Token向新浪围脖发消息了
        storeAccessToken(accessToken.getToken(), accessToken.getTokenSecret());
      }

      weibo.setToken(accessToken.getToken(), accessToken.getTokenSecret());

      System.out.println("Input message to sina:");
      String message = readLine();
      while (!"exit".equals(message.trim())) {
        weibo.updateStatus(message);
        System.out.println("Input message to sina:");
        message = readLine();
      }
    } catch (WeiboException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private static void storeAccessToken(String token, String tokenSecret) throws IOException {
    OutputStream out = new FileOutputStream(new File(FILE_NAME));
    Properties p = new Properties();
    p.setProperty(ACCESS_TOKEN, token);
    p.setProperty(ACCESS_SECRET, tokenSecret);
    p.store(out, "sina access token");
    out.flush();
    out.close();
  }

  private static AccessToken loadAccessToken() throws IOException {
    File f = new File(FILE_NAME);
    if (!f.exists()) {
      return null;
    }
    InputStream in = new FileInputStream(f);
    PropertyResourceBundle bundle = new PropertyResourceBundle(in);
    in.close();
    return new AccessToken(bundle.getString(ACCESS_TOKEN), bundle.getString(ACCESS_SECRET));
  }

  private static String readLine() throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    byte[] bs = reader.readLine().getBytes("gbk");
    return new String(bs);
  }
}

Comments