2009/09/06

AppEngine for JavaでTwitter4Jを使ってみる

Twitter4JはTwitter APIをJavaでラップしたライブラリです。
こちらのサイト↓で提供されています。
http://yusuke.homeip.net/twitter4j/ja/index.html

普通に使う分にはzip版をダウンロードして「twitter4j-x.x.x.jar」を利用すればよいでしょう。

もし、自分でコードを変更してビルドしたい場合はantを使ってビルドすることができます。
以下のようにEclipseのプラグインに入っているantを利用すると簡単です。

> set PATH=%PATH%;C:\Program Files\eclipse3.5\eclipse\\plugins\org.apache.ant_1.7.0.v200803061910\bin
> set ANT_OPTS=-Dfile.encoding=UTF8
> ant

使い方はいたって簡単、ID,パスワードを指定してTwitterクラスのインスタンスを作成して、getUserTimeLine()だとかgetFriendsTimeline()を呼び出すだけです。

Twitter twitter = new Twitter(id, password);
for (Status status : twitter.getUserTimeline()) {
System.out.println(status.getCreatedAt().toLocaleString());
System.out.println(status.getText());
}

さて、今回はこれをGoogle App Engine for Javaで利用してみたいと思います。

App Engine for Javaで開発するにはEclipse + GAE pluginという組み合わせを強くお勧めします。
解説については本家のUsing the Google Plugin for Eclipseスタートガイドを読むとよいでしょう。

GWTも同時に入れた時の注意点としては、アプリケーションの雛型作成のときに「GWTを使用する」のチェックボックスをオフにすることです。
GWTを使うと雛型が複雑になってしまうので今回のアプリには必要ありません。

App Engineでthird partyライブラリであるTwitter4Jを使うには、jarファイルをプログラムと一緒にデプロイするように設定する必要があります。
設定手順は以下のとおりです。

  1. twitter4j-x.x.x.jarをwar\WEB-INF\libにコピーする

  2. EclipseのProject Explorerでwar\WEB-INF\libを開き、Refresh(F5)してjarファイルが表示されることを確認する

  3. EclipseでProject Propertyを開き、Java Build Path - LibrariesにおいてAdd Jarsでtwitter4j-x.x.x.jarを追加する


これでTwitter4JをApp Engineで使う準備が整いました。

とりあえず、自分のタイムラインを整形して表示してみようと思います。
最新20件だけでは簡単すぎるので次ページ、前ページでリンクを表示して履歴が見えるようにしてみます。

タイムラインのページを操作するにはgetUserTimeline()にPagingというパラメータを与えて次のように呼び出します。

Twitter twitter = new Twitter(id, password);
List statuses = twitter.getUserTimeline(new Paging(page, numPage));


また、このページ数をCGI parameterで処理するようにします。
CGI parameterの取得、解釈及び、prev/nextのリンク表示は以下のようになります。

int page = 0;
try {
page = Integer.parseInt(req.getParameter("page"));
} catch(Exception e) {
// do nothing
}
page = (page > 0) ? page : 1;
//
// some code
//
if (page > 1) {
out.println("<a href=\"" + req.getContextPath() + "?page=" + integer.toString(page - 1) + "\">prev</a>");
}
out.println("<a href=\"" + req.getContextPath() + "?page=" + Integer.toString(page + 1) + "\">next</a>");


Timelineの整形部分を含めた最終的なコードは次のようになります。

package yourpackage;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Paging;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;

@SuppressWarnings("serial")
public class TwitterTimelineServlet extends HttpServlet {
private static final String TWITTER_ID = "your twitter ID";
private static final String TWITTER_PASSWORD = "your twitter password";

List<Status> getTwitterTimeline(String id, String password, int page, int numPage) {
try {
Twitter twitter = new Twitter(id, password);
return twitter.getUserTimeline(new Paging(page, numPage));
} catch (TwitterException e) {
e.printStackTrace();
}
return new ArrayList<Status>();
}

String formatTimeline(List<Status> statuses) {
StringBuffer sb = new StringBuffer();

SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat timeFmt = new SimpleDateFormat("HH:mm");
dateFmt.setTimeZone(TimeZone.getTimeZone("JST"));
timeFmt.setTimeZone(TimeZone.getTimeZone("JST"));

Collections.reverse(statuses);
String prevDate = null;
for (Status status : statuses) {
String currDate = dateFmt.format(status.getCreatedAt());
if (!currDate.equals(prevDate)) {
sb.append((prevDate != null) ? "\n" : "");
sb.append(currDate + "\n");
}
sb.append("  " + timeFmt.format(status.getCreatedAt())
+ " " + status.getText().replaceAll("\n", "\n      ") + "\n");
prevDate = currDate;
}

return sb.toString();
}

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");

int page = 0;
try {
page = Integer.parseInt(req.getParameter("page"));
} catch(Exception e) {
// do nothing
}
page = (page > 0) ? page : 1;

PrintWriter out = resp.getWriter();
out.println("<html>" +
"<head>" +
"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />" +
"</head>" +
"<body><pre>");

String timeline = formatTimeline(getTwitterTimeline(TWITTER_ID, TWITTER_PASSWORD, page, 20));

out.println("Twitter timeline for " + TWITTER_ID);
out.println(timeline);

out.println("</pre>");
if (page > 1) {
out.println("<a href=\"" + req.getContextPath() + "?page=" + Integer.toString(page - 1) + "\">prev</a>");
}
out.println("<a href=\"" + req.getContextPath() + "?page=" + Integer.toString(page + 1) + "\">next</a>");
out.println("</body></html>");
}
}

どうだったでしょうか。
Twitter4Jのおかげでとても簡単にTwitterから情報を取得できました。

今度はTwitter4Jは使って応用的なプログラムを作ってみようと思います。

0 件のコメント:

コメントを投稿