10分くらいでWebAPIを叩く

JavaAdventCalendar-ja2010の12/19分エントリです。

昨日のエントリ(さくらばさん):Project Coin


クリスマスも近づきJavaAdventCalendar-ja2010ももう終盤です。
今日は簡単にWebAPIを叩くためのコードについて紹介します。最近は多くのWebサービスでWebAPI経由で
情報を引き出す事ができます。最近でははてなでもWebAPIも公開されました。mixifacebookなどのSNS
のWebAPIもありますし、ニコニコ動画では動画情報を引き出すことができます。
なぜか、この手のサンプルはJavaで書かれたものがないので今回はJavaで実装してみました。解説用に
ベタ書きしていますので処理の流れをこのソースで確認して頂ければとおもいます。

基本的な流れ

基本的な処理手順は指定されたURLにアクセスしてその内容を取得するだけです。注意しなければなら
ないのはサービスによって指定された認証方法やリクエストを送信しなければならないところです。
例えばニコニコ動画APIだとサムネイル情報や動画情報を取得するgetthumbinfoでは動画IDをGET送信
するだけですが、動画URLを取得するgetflvではログイン情報のcookieと動画IDをPOST送信しなけれ
ばなりません。

コードサンプル

この辺の実装はhttpComponentsを利用すると楽にできます。
このサンプルではニコニコ動画でログインとgetflvで情報を取得します。

1.https://secure.nicovideo.jp/secure/login?site=niconicoにmailとpasswordをPOST送信する
2.Cookieを取得する
3.上で取得したCookieを利用してgetFlvにアクセス
4.情報を取得
という事を行っています。

package org.kirino;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

public class NikoApi {
	private static final String LOGIN_URL = "https://secure.nicovideo.jp/secure/login?site=niconico";
	private static final String MAIL_ADDRESS = "****";
	private static final String PASSWORD = "*****";

	public static void main(String[] args) throws ClientProtocolException,
			IOException {
		DefaultHttpClient client = new DefaultHttpClient();
		client.getParams().setParameter(ClientPNames.COOKIE_POLICY,
				CookiePolicy.BROWSER_COMPATIBILITY);
		client.getParams().setParameter("http.connection.timeout", 5000);
		client.getParams().setParameter("http.socket.timeout", 3000);

		HttpPost post = new HttpPost(LOGIN_URL);

		// POSTするパラメータ
		ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();

		// mail
		params.add(new BasicNameValuePair("mail", MAIL_ADDRESS));
		// password
		params.add(new BasicNameValuePair("password", PASSWORD));

		post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
		HttpResponse response = client.execute(post);
		Header[] headers = response.getAllHeaders();
		for (Header h : headers) {
			System.out.println(h.getName() + ":" + h.getValue());
		}
		// cookie保存
		CookieStore cookieStore = client.getCookieStore();
		client.getConnectionManager().shutdown();

		// getFlvを実行する
		DefaultHttpClient clientFlv = new DefaultHttpClient();
		clientFlv.setCookieStore(cookieStore);
		HttpPost postFlv = new HttpPost(
				"http://flapi.nicovideo.jp/api/getflv/sm6119955");
		HttpResponse responseFlv = clientFlv.execute(postFlv);
		HttpEntity entity = responseFlv.getEntity();
		System.out.println(EntityUtils.toString(entity, "utf-8"));
		clientFlv.getConnectionManager().shutdown();
		System.out.println("end");

	}

}

解説するよ!

		DefaultHttpClient client = new DefaultHttpClient();
		client.getParams().setParameter(ClientPNames.COOKIE_POLICY,
				CookiePolicy.BROWSER_COMPATIBILITY);
		client.getParams().setParameter("http.connection.timeout", 5000);
		client.getParams().setParameter("http.socket.timeout", 3000);

httpClientの設定です。Cookieの利用ポリシーをブラウザ準拠にするのとタイムアウトの設定を
行っています。この辺はどのWebAPIを叩く場合もほとんど一緒です。

		HttpPost post = new HttpPost(LOGIN_URL);

		// POSTするパラメータ
		ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();

		// mail
		params.add(new BasicNameValuePair("mail", MAIL_ADDRESS));
		// password
		params.add(new BasicNameValuePair("password", PASSWORD));

POSTするデータの設定です。BasicNameValuePairというクラスのオブジェクトにkey,valueを入れて
おきます。最後にそれらをまとめるListにいれておけばOK

		post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
		HttpResponse response = client.execute(post);
		Header[] headers = response.getAllHeaders();
		for (Header h : headers) {
			System.out.println(h.getName() + ":" + h.getValue());
		}

コネクションを張ってデータを取得します。サンプル用にrespons headerを表示しています。
webAPIを実行してうまく行かない場合は大抵respons headerに何かしらメッセージが入っているので
それを参考にしながらデバッグするといいでしょう。

		CookieStore cookieStore = client.getCookieStore();
		client.getConnectionManager().shutdown();

cookieを取得した後に切断してます。後始末大事!!

		DefaultHttpClient clientFlv = new DefaultHttpClient();
		clientFlv.setCookieStore(cookieStore);
		HttpPost postFlv = new HttpPost(
				"http://flapi.nicovideo.jp/api/getflv/sm6119955");
		HttpResponse responseFlv = clientFlv.execute(postFlv);
		HttpEntity entity = responseFlv.getEntity();
		System.out.println(EntityUtils.toString(entity, "utf-8"));

今度はgetflvを実行しています。基本的な流れはログインと同じです。
response bodyを表示させるときはEntityUtils.toStringを利用すると楽に表示できます。

まとめ


今回は基本的なパターンでcookie取得とデータを取得するパターンをご紹介しました。ニコニコ動画API
についてはニコニコ動画APIリファレンスを参考にしました。*1
twitterやhatenaの場合、OAuthでの認証が必要になるため手順が増えますが基本的なところはこの流れ
になります。ただOAuthの場合はライブラリを利用してアクセスする方が楽かとおもいます。

明日はEmacs使いid:nekopです。

*1:というか公式のドキュメントが見つからない