HttpClient 4.5 の利用

以前作成したアプリをちょっと改修する必要があったので HttpClient 4.5 に切り替えしました。 ライブラリだけは4.3だったので非推奨の警告が大量に出ている状態でした。

4.3からは各種Factoryクラス/builderメソッドを使う形になっています。
4.3/4.4で追加されたクラスが4.5で非推奨になっていて、結局ソースコードを見る羽目になった。
例えば org.apache.http.conn.ssl にはSSLSocketFactory、SSLContextBuilderがあるが、4.4から非推奨となっている。 SSLSocketFactory は、SSLConnectionSocketFactoryを利用することになるが、SSLContextBuilderは別パッケージ(org.apache.http.ssl)となる。
厳密には別パッケージどころかjarが違う(前者はhttpclient、後者はhttpcomponents-core)。

以下はHttpClientを生成する処理

SSLContext sslContext = SSLContexts.custom().useProtocol( "TLS" ).build();
// TrustManagerのオーバーライド 証明書の認証を無効化
X509TrustManager trustManager = new X509TrustManager() {
    @Override
    public void checkClientTrusted ( X509Certificate[] xcs, String string ) throws CertificateException {
    }
    @Override
    public void checkServerTrusted ( X509Certificate[] xcs, String string ) throws CertificateException {
    }
    @Override
    public X509Certificate[] getAcceptedIssuers () {
        return null;
    }
};
sslContext.init( null, new TrustManager[]{trustManager}, null );
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory( sslContext,
        new String[]{"TLSv1","TLSv1.1","TLSv1.2"},//サポートするTLSのVersion
        null,
        new HostnameVerifier() {
            @Override
            public boolean verify ( String arg0, SSLSession arg1 ) {
                return true;// すべてのサーバーを許可
            }
        } );
// Registry
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()
        .register( "http", PlainConnectionSocketFactory.getSocketFactory() )
        .register( "https", sslConnectionSocketFactory ).build();
// Connection Manager
PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager( registry );
manager.setMaxTotal( 100 );
manager.setDefaultMaxPerRoute( 20 );
// Request Configurations
RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout( 30*1000 )
        .setSocketTimeout( 30*1000 ).build();
// Headers
List<Header> headers = new ArrayList<>();
headers.add( new BasicHeader( "Accept-Charset", "utf-8" ) );
headers.add(new BasicHeader("Accept-Language", "ja, en;q=0.8"));
headers.add( new BasicHeader( "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36" ) );
HttpClient httpClient = HttpClients.custom()
        .setSSLSocketFactory( sslConnectionSocketFactory )
        .setDefaultRequestConfig( requestConfig )
        .setDefaultHeaders( headers )
        .setConnectionManager( manager ).build();
return httpClient;

尚、イントラネット内部での利用が前提となっているアプリのため、認証はすべてスルーしています。 当然公開アプリでこのままコピペするとひどいことになる。

HTTP Over TLSについては、RFC2818を参照 http://www.ipa.go.jp/security/rfc/RFC2818JA.html