S-JIS[2010-09-08/2010-09-12] 変更履歴
Twitter4Jは、Twitterへアクセスする為のJavaのライブラリー。
Twitterへアクセスする為の公式なTwitter APIはHTTPで呼び出すので、それを理解していればHTTPクライアントを作るだけでアクセスできるようだが、その部分をTwitter4Jがライブラリー化してくれている。
したがって、Twitter4Jのクラス・メソッドを使用してTwitterにアクセスできる。
ちなみに、twitter4j-examples-2.1.3.jarはTwitter4Jのサンプルプログラム。ソースは「C:\workspace\twitter\twitter4j-2.1.3\twitter4j-examples\src\main\java」。
twitter4j-examplesのGetTimelinesクラスを参考に、タイムライン(TL)を取得して表示してみる。
import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import java.util.List;
public final class GetTimelines {
public static void main(String[] args) {
System.out.println("■factory.");
Twitter twitter = new TwitterFactory().getInstance(); //認証なしで接続
System.out.println("■Showing public timeline.");
try {
List<Status> statuses = twitter.getPublicTimeline(); //パブリックタイムラインの取得
for (Status status : statuses) {
System.out.println(status.getUser().getName() + ":" + status.getText());
}
} catch (TwitterException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
TwitterFactory#getInstance()を呼ぶと、コンソールにログが出力される。
Twitter#getPublicTimeline()を呼ぶと、パブリックタイムラインのツイートが取得される。
■factory. [Wed Sep 08 02:37:15 JST 2010]Will use class twitter4j.internal.logging.StdOutLoggerFactory as logging factory. [Wed Sep 08 02:37:16 JST 2010]Will use twitter4j.internal.http.HttpClientImpl as HttpClient implementation. ■Showing public timeline. 〜
Twitter#getUserTimeline()で、特定ユーザーのツイートが取得できる。
List<Status> statuses = twitter.getUserTimeline("hishidama");
Twitter#showStatus()で、特定のツイート(ステータス)が取得できる。
Status status = twitter.showStatus(81642112L);
twitter4j-examplesのGetTimelinesクラスには、ユーザーID・パスワードを指定してタイムラインを取得するサンプルも入っている。
Twitter twitter = new TwitterFactory().getInstance(userId, password);
しかしこれはBasic認証を使用する方法であり、Basic認証は現在廃止になっているので、実行するとエラーになる。
Failed to get timeline: 401:Authentication credentials were missing or incorrect.
{"errors":[{"code":53,"message":"Basic authentication is not supported"}]}
クライアントアプリケーションでOAuth認証を使ってみる。[2010-09-11]
(OAuth認証を使う為には、事前に自分のアプリケーション専用の認証情報をTwitterから発行してもらう必要がある)
参考: Twitter4JのコードサンプルのOAuth認可
import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.http.AccessToken; import twitter4j.http.RequestToken; import java.awt.Desktop; import java.io.IOException; import java.net.URI; import javax.swing.JOptionPane;
private static final String CONSUMER_KEY = "Twitter登録時に表示されたConsumer key"; private static final String CONSUMER_SECRET = "Twitter登録時に表示されたConsumer secret";
public Twitter loginOAuth() throws TwitterException {
Twitter twitter = new TwitterFactory().getOAuthAuthorizedInstance(CONSUMER_KEY, CONSUMER_SECRET);
getOAuthAccessToken(twitter);
return twitter;
}
AccessToken getOAuthAccessToken(Twitter twitter) throws TwitterException {
//■リクエストトークンの作成
RequestToken requestToken = twitter.getOAuthRequestToken();
String url = requestToken.getAuthorizationURL();
// System.out.println("AuthorizationURL\t" + url);
//■ブラウザーでTwitterの認証画面を表示する(ここでTwitterにログインすることにより、暗証番号が表示される)
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(URI.create(url));
} catch (IOException e) {
throw new TwitterException(e);
}
//■暗証番号の入力を求めるダイアログ
String pin = JOptionPane.showInputDialog("暗証番号を入力して下さい");
if (pin == null) {
throw new TwitterException("暗証番号の入力がキャンセルされました");
}
pin = pin.trim();
//■アクセストークンの作成(認証)
try {
AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, pin);
// System.out.println("AccessToken\t" + accessToken);
return accessToken;
} catch (TwitterException e) {
// System.out.println(e.getStatusCode()); //拒否されると401
throw e;
}
}
Consumer key/secretは、自分のアプリケーション固有の値。
OAuthの登録を行った時に表示された英数字の羅列をコピペする。
https://twitter.com/oauth/authorize?oauth_token=hogehogeufufu」といった感じ
。「oauth_token=」以降は毎回変わる)過去に表示された暗証番号は再使用できないようだ。アクセストークン作成時にエラーになる。
一度認証されたアクセストークンは、保持しておけば何度でも使える。[2010-09-12]
(いちいち暗証番号を確認したり入力したりする必要が無くなる)
以下、シリアライズを使ってアクセストークンをファイルに保存しておく例。
public Twitter loginOAuth(String name) throws TwitterException {
Twitter twitter;
AccessToken accessToken = loadAccessToken(name);
if (accessToken != null) {
// 保存されていたアクセストークンを使う
twitter = new TwitterFactory().getOAuthAuthorizedInstance(CONSUMER_KEY, CONSUMER_SECRET, accessToken);
} else {
// 認証して暗証番号を入力してもらい、アクセストークンを保存する
twitter = new TwitterFactory().getOAuthAuthorizedInstance(CONSUMER_KEY, CONSUMER_SECRET);
accessToken = getOAuthAccessToken(twitter);
storeAccessToken(name, accessToken);
}
return twitter;
}
// アクセストークンをファイルから読み込む
AccessToken loadAccessToken(String name) {
File f = createAccessTokenFileName(name);
ObjectInputStream is = null;
try {
is = new ObjectInputStream(new FileInputStream(f));
AccessToken accessToken = (AccessToken) is.readObject();
return accessToken;
} catch (IOException e) {
return null; //ファイルが読めない(存在しない)場合はnullを返す
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (is != null) {
try { is.close(); } catch (IOException e) { e.printStackTrace(); }
}
}
}
// アクセストークンをファイルに保存する
void storeAccessToken(String name, AccessToken accessToken) {
File f = createAccessTokenFileName(name);
File d = f.getParentFile();
if (!d.exists()) {
d.mkdirs();
}
ObjectOutputStream os = null;
try {
os = new ObjectOutputStream(new FileOutputStream(f));
os.writeObject(accessToken);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try { os.close(); } catch (IOException e) { e.printStackTrace(); }
}
}
}
// アクセストークンを保存するファイル名を生成する
File createAccessTokenFileName(String name) {
String s = System.getProperty("user.home") + "/.twitter/client/sample/accessToken_" + name + ".dat";
return new File(s);
}
OAuth認証を使ってツイート(つぶやきを投稿)する例。[2010-09-11]
void tweet() {
try {
Twitter twitter = loginOAuth(); //毎回暗証番号を入力
// Twitter twitter = loginOAuth("hishidama"); //初回だけ暗証番号を入力[2010-09-12]
twitter.updateStatus("Twitter4Jで投稿する実験");
// twitter.updateStatus("リツィートする実験 RT @hishidama 実験", ステータスID);
} catch (TwitterException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
参考: 18.updateStatus() - 陽昇れども地の底に光届かず
ちなみに、アプリをOAuthに登録した際に「Read-only(読取専用)」にしていると、例外が発生して投稿できない。
401:Authentication credentials were missing or incorrect.
{"request":"/1/statuses/update.json","error":"Read-only application cannot POST"}
TwitterException{exceptionCode=[15bb6564-00e304a2], statusCode=401, retryAfter=0, rateLimitStatus=null, version=2.1.3}
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:307)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:72)
at twitter4j.internal.http.HttpClientWrapper.post(HttpClientWrapper.java:103)
at twitter4j.Twitter.updateStatus(Twitter.java:496)
at jp.hishidama.twitter.sample.GetTimelines.tweet(Sample.java:201)
at jp.hishidama.twitter.sample.GetTimelines.main(Sample.java:60)