2013年11月15日金曜日

Jersey ApacheHttpClientをつかう

Javaでhttpから何かを取得する場合に、
一番簡単に扱えてかつ拡張性が高いのは
Jersey ApacheHttpClient だとおもいますという話。


通常の使い方


ApacheHttpClientの特徴は、オブジェクトマッピングをしてくれるという点です

String型で取得する場合は次のようにすればよい


String res = ApacheHttpClient.create().resource(urlString).get(String.class);


一行ですんじゃいます。

またJSONやXMLを取得する場合にJAXBによる変換を行うことができます。
取得するXMLがつぎのような場合、

<?xml version="1.0"?>
<date>2012/10/11</date>
<hash>hogehogegeee</hash>
<rank>1</rank>
<value>2</value>
<addTime>2012/10/11 12:00</addTime>

マッピングをするクラスを次のように定義して、

Ranking.java :

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement
public class Ranking {
    @XmlElement
    public Date date;

    @XmlElement
    public String hash;

    @XmlElement
    public int rank;

    @XmlElement
    public long value;

    @XmlElement
    public Date addTime;


    public Ranking(){}

}


で、次のようにすれば指定したクラスにマッピングして取得することができます。

Ranking ranking = restClient.resource(urlString).get(Ranking.class);

 

 

 

よくある設定


タイムアウトの設定
接続タイムアウト

ApacheHttpClient client = ApacheHttpClient.create();
client.setConnectTimeout(360000);

読み込みタイムアウト

client.setReadTimeout(900000);



フィルターの定義


フィルターを定義することによって、通信の前後の挙動を
ファンクションクラス?として定義して使いまわすことができます。


Cookieの管理  

クッキーは検証してないのですが、コンフィグで渡せば使えそうです。
クッキーを管理してセッション等を保持する場合は下のような
フィルターを登録すればよいようです。


ApacheHttpClientConfig config = new DefaultApacheHttpClientConfig();
config.getProperties().put(ApacheHttpClientConfig.PROPERTY_HANDLE_COOKIES, true);

ApacheHttpClient client = ApacheHttpClient.create(config);
client.addFilter(new ClientFilter() {
    private ArrayList cookies = new ArrayList();

    @Override
    public ClientResponse handle(ClientRequest request)
            throws ClientHandlerException {
        if (cookies != null) {
            request.getHeaders().put("Cookie", cookies);
        }

        ClientResponse response = getNext().handle(request);
        if (response.getCookies() != null) {
            if (cookies == null) {
                cookies = new ArrayList();
            }
            cookies.addAll(response.getCookies());
        }
        return response;
    }
});



単にCookieを渡したいだけならWebResourceから指定もできます。


ApacheHttpClient client = ApacheHttpClient.create();

String res = client
        .resource(url)
        .header(HttpHeaders.COOKIE, cookieString)
        .get(String.class);

 

 

 

UserAgentの設定

UserAgentの設定は2つの方法があります。
Jersey Clientと同じようにFilterで登録するかWebResourceにヘッダーを追加する方法です。


Filterを追加する場合:

ApacheHttpClient client = ApacheHttpClient.create();

client.addFilter(new ClientFilter() {
    @Override
    public ClientResponse handle(ClientRequest request)
            throws ClientHandlerException {
        request.getHeaders().put("UserAgent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9b5) Gecko/2008032619 Firefox/3.0b5");
        return getNext().handle(request);
    }
});



WebResourceに追加する場合:

ApacheHttpClient client = ApacheHttpClient.create();

String res = client
        .resource(url)
        .header(HttpHeaders.USER_AGENT, userAgent)
        .get(String.class);



プロキシの設定

HTTP プロクシの設定にはApacheHttpClientConfigを
Client作成時に渡します。


ApacheHttpClientConfig config = new DefaultApacheHttpClientConfig();
config.getProperties().put(
                        ApacheHttpClientConfig.PROPERTY_PROXY_URI,
                        "proxyurl");

ApacheHttpClient client = ApacheHttpClient.create(config);

SocksプロクシとHTTPプロクシの優先順位

SocksプロクシにはApacheHttpClient自体は対応していないので、
Java自体の機能を利用します。


System.setProperty("socksProxyHost", "127.0.0.1");
System.setProperty("socksProxyPort", "9050");



SocksプロクシとApacheHttpClientのconfigでのプロクシの設定は
同時に利用可能です。両方設定した場合、Socksが優先されます。