2010年01月12日

【Java】HttpComponentsを使ってみる

HttpComponentsは、昔はCommons HttpClientという名前で配布されていたJavaでHTTPリクエストを行う為のライブラリ。

Cookieを使った通信とかが簡易にできるので、クローラーなどを作る際には重宝する。

HttpComponentsの公式サイトはこちら
http://hc.apache.org/

簡易な通信の例。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

public class Test {

public static void main(String[] args) throws ClientProtocolException {

DefaultHttpClient client = new DefaultHttpClient();

// GETでリクエストするクラスの生成
HttpGet httpGet = new HttpGet("http://www.yahoo.co.jp/");

InputStream is = null;
HttpEntity entity = null;

try {
// リクエストを実行してみる
HttpResponse response = client.execute(httpGet);
entity = response.getEntity();

// entityが取れなかった場合は、Connectionのことは心配しないでもOK
if (entity != null) {

is = entity.getContent();

// コンテンツの読み込み
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String line;
while( ( line = reader.readLine() ) != null )
System.out.println(line);
}
} catch (IOException ex) {
// 入出力例外は起きるもの
ex.printStackTrace();
} catch (RuntimeException ex) {
// 予期しない例外が起きた時は、HttpGetのabortを実行し、
// ConnectionをリリースしてConnectionManagerに返す
httpGet.abort();
throw ex;
} finally {
try {
is.close();
entity.consumeContent();
} catch(IOException e) {}
}

// 終了処理
// Clientは複数のリクエストを発行可能。使わなくなったらshutdownする。
client.getConnectionManager().shutdown();
}
}



ResponseHandlerを使うと、もっと簡単にコンテンツが取得できる。但し、デフォルトで用意されているBasicResponseHandlerは、レスポンスコードが300未満のもの以外は例外をThrowしたり、エンコード等に気を遣っていないので、自前でResponseHandlerを継承してクラスを作った方が良さげ。

とりあえずBasicResponseHandlerを使うと、こういった書き方でコンテンツの内容を返してくれる。


HttpClient client = new DefaultHttpClient();

HttpGet httpGet = new HttpGet("http://www.yaho.co.jp/");

// デフォルトで用意されているBasicResponseHandlerを使用してみる
ResponseHandler responseHandler = new BasicResponseHandler();

// execute時に引数に追加すると、ResponseHandlerのhandleResponseが
// 実行された際に返ってくる値を取得できる
String responseBody = client.execute(httpGet, responseHandler);

// これでbodyを出力できて、とても簡単
System.out.println(responseBody);

client.getConnectionManager().shutdown();



自前でResponseHandlerを作るのはとても簡単。ResponseHandlerをimplementsして、handleResponseを実装するだけで済む。

例えばレスポンスコードを返すだけのResponseHandlerだったらこんな感じで書くっぽい。


public class Test {
public static void main(String[] args)
throws ClientProtocolException, IOException {

HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://www.yahoo.co.jp/");
ResponseHandler<Integer> responseHandler = new CodeResponseHandler();
Integer responseCode = client.execute(httpGet, responseHandler);
System.out.println(responseCode);
client.getConnectionManager().shutdown();
}
}

class CodeResponseHandler implements ResponseHandler<Integer> {
public Integer handleResponse(final HttpResponse response) {
StatusLine statusLine = response.getStatusLine();
return statusLine.getStatusCode();
}
}