HttpClient3.1 チュートリアル

感想おまちしてます!

ひさびさにHttpClientを使うことになったので、ユーザガイドのチュートリアルをもとにまとめる。

原文サイト
Jakarta Commons HttpClient Tutorial
ちなみに上の原文サイトでは、HttpClient3.0を元に解説している。

スポンサーリンク

Getting Ready

HttpClientの依存関係はdependenciesに書いてある。
commons-codecとcommons-loggingが必要。

Concepts

一般的なHttpClientの使い方は以下のステップになる。

  • HttpClientのインスタンスを作成する。
  • メソッドにあわせた(ここではGetメソッド)インスタンスを作成する。接続するURLはメソッドのコンストラクタに与える
  • メソッドを実行する
  • レスポンスを読み込む
  • コネクションを開放する
  • レスポンスを処理する

HttpClientの接続を開放するときには、接続が再利用可能かを確認することが必要となる。

Instantiating HttpClient

引数なしのコンストラクタだと、デフォルトの値が使われる。大体の場合、これでOKな設定になっている。

HttpClient client = new HttpClient();

Creating a Method

org.apache.commons.httpclient.methodsに定義されているメソッドを利用できる。

HttpMethod method = new GetMethod("http://www.apache.org/");

Execute the Method

executeMethodを使ってメソッドを実行する。
このメソッドはサーバのステータスコードを戻り値にしている。

int statusCode = client.executeMethod(method);

executeMethodによって投げられる例外は2種類。ひとつはHttpException、もうひとつは、IOException。
例外に関する詳細はthe HttpClient exception handling guideを参考のこと。

HttpException

HttpExceptionは論理エラーを表している、この例外はリクエストが送れなかった場合や、HTTP仕様に従っていないという致命的違反のために、処理できなかった場合に発生する。通常回復できないそうだ。

IOException

IOException ( HttpExceptionのサブクラス)は転送エラーやI/Oの問題が発生した場合に発生する可能性が高い。リトライして回復する場合がある。

Method recovery

HttpClientはIOExceptionが発生する間、自動でリトライを行うことができる。デフォルトでは3回のリトライを行う。
デフォルト値は
org.apache.commons.httpclient.params.DefaultHttpParamsFactory.getDefaultParamsから呼び出されているcreateParamsで設定されていた。getDefaultParamsメソッドはシングルトンになっている。

 // createParamsメソッド
params.setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());

つまり、以下と同じことをしていることになる。

 client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,  new DefaultHttpMethodRetryHandler());

独自の設定に書き換えることもできる。

 DefaultMethodRetryHandler retryhandler = new DefaultMethodRetryHandler(10, true);
client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryhandler);

サーバで処理されている時や、レスポンスでIOExceptionが発せしたときでもリトライは可能。
リトライはGETならば安全、POSTやPUTは危険らしい。
ウェイトさせてのリトライは、HttpClient でウェイト付きリトライを行う。 by 考え得る最高を常に行うさんにいい感じのがのってます。

Read the Response

レスポンスの読み込みはReadOnly。もっともシンプルなのがByte配列での読み込み。

byte[] responseBody = method.getResponseBody();

レスポンスの読み込み方法は以下の3つがある。

  • method.getResponseBody()を使ってバイト配列出の読み込む
  • method.getResponseBodyAsString()を使って文字列で読み込む。デフォルトの文字エンコーディングを使ってByte[]からStringへの変換を行う。すべてのプラットフォームで使えない可能性がある
  • method.getResponseBodyAsStream()を使ってstreamで読み込む。大量データの場合はこれが一番良い。読み込みが終了したらstream.close()を呼び出すこと

Release the Connection

コネクションの終了とともに、接続を再利用できるということをHttpClientに伝える必要がある。

method.releaseConnection();

接続のリリースがなければ、HttpClientは、接続を再利用するため、コネクションの解放を無期限に待つ。危険なので忘れずに。

ソースを読んでみたけど、HttpMethodを実装しているHttpMethodBaseクラスが持っているHttpConnectionクラスをCloseしているみたい
この辺はまた調べようー。

Deal with the Repsonse

HttpClientを使えばレスポンスの処理に集中できる。
ここで注意するのは、文字エンコーディング。デフォルトだと、デフォルトの文字エンコーディングになる。

Final Source Code

これまでをまとめたソースコード。

 import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpMethodParams;
import java.io.*;
public class HttpClientTutorial {
private static String url = "http://www.apache.org/";
public static void main(String[] args) {
// Create an instance of HttpClient.
HttpClient client = new HttpClient();
// Create a method instance.
GetMethod method = new GetMethod(url);
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
// Execute the method.
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
// Read the response body.
byte[] responseBody = method.getResponseBody();
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
System.out.println(new String(responseBody));
} catch (HttpException e) {
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
} finally {
// Release the connection.
method.releaseConnection();
}
}
}

参考