httpcomponents-client-4.0.1

バージョン3のときとは,インターフェースが完全に変わっている。

単純にHTMLを取得したければ, 以下のようにすればよい

import java.io.IOException;

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


public class HttpClientSample {


	public static String url = "http://www.google.co.jp/";


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

		DefaultHttpClient client = new DefaultHttpClient();

		// Get method
		HttpGet httpget = new HttpGet(url);
		HttpResponse response = client.execute(httpget);

		System.out.println(response.getStatusLine());

		client.getConnectionManager().shutdown();
	}
}


但し, 同一のHttpClientインスタンスから再度リクエストを飛ばすと, 以下の例外が発生する。

Exception in thread "main" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
	at org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:199)
	at org.apache.http.impl.conn.SingleClientConnManager$1.getConnection(SingleClientConnManager.java:173)
	at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:390)
	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
	at ksato.http.sample.HttpClientSample.main(HttpClientSample.java:30)


リリース処理をはさんでも駄目(そもそもリリース処理の書き方が間違っている可能性あり)。

		SingleClientConnManager manager = (SingleClientConnManager) client.getConnectionManager();
		ManagedClientConnection connection =
			manager.getConnection(new HttpRoute(new HttpHost("www.google.co.jp")), null);
		manager.releaseConnection(connection, 0, null);


対処法は2つ。

  • HttpClientインスタンスを作り直す(再度newする)。
  • ClientConnectionManagerをHttpClientに渡してやる(↓サンプル)。
import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;

public class HttpClientSample3 {

	public static String url = "http://www.google.co.jp/";

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

		HttpParams params = new BasicHttpParams();
		SchemeRegistry registry = new SchemeRegistry();
		registry.register(new Scheme("http",
				PlainSocketFactory.getSocketFactory(), 80));
		ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
		DefaultHttpClient client = new DefaultHttpClient(ccm, params);

		// Get method
		HttpGet httpget = new HttpGet(url);
		HttpResponse response = client.execute(httpget);

		System.out.println(response.getStatusLine());

		// second
		HttpGet second = new HttpGet(url);
		HttpResponse res2 = client.execute(second);

		System.out.println(res2.getStatusLine());


		client.getConnectionManager().shutdown();
	}
}

ClientConnectionManagerインスタンスを生成するところで, HttpParamsインスタンス
渡してるけど, その後でHttpClient生成時にも渡す必要あんのね。なんでだろ。