Computing Magazine

How to Use Apache HttpClient 4.5 for Https Connections

Posted on the 13 February 2017 by Abhishek Somani @somaniabhi
This is a simple example on how to use Apache HttpClient 4.5 with connection pool manager to request https urls .

package com.javaroots;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.net.ssl.*;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.javaroots.DummyTrustManager;
public class HttpClientFactory {
private static CloseableHttpClient client;
private static PoolingHttpClientConnectionManager connPool = null;
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientFactory.class);
static{
try
{
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(new TrustSelfSignedStrategy()).build();
sslcontext.init(new KeyManager[0], new TrustManager[] { new DummyTrustManager() }, new SecureRandom());
sslcontext.init(null, new X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());
SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
new HostnameVerifier() {
@Override
public boolean verify(final String s, final SSLSession sslSession) {
return true;
}
});
Registry r = RegistryBuilder. create()
.register("https", factory).build();
connPool = new PoolingHttpClientConnectionManager(r);
// Increase max total connection to 200
connPool.setMaxTotal(200);

connPool.setDefaultMaxPerRoute(20);
client = HttpClients.custom().
setConnectionManagerShared(true).
setConnectionManager(connPool).
setSSLSocketFactory(factory).build();
}
catch(Exception e){
LOGGER.error("Error initiliazing HttpClientFactory :: ",e);
}
}
public static CloseableHttpClient getHttpsClient() throws KeyManagementException, NoSuchAlgorithmException {
if (client != null) {
return client;
}
throw new RuntimeException("Client is not initiliazed properly");
}
public static void releaseInstance() {
client = null;
}
}
In above code if you do not use setConnectionManagerShared(true) , you might get following error .

java.lang.IllegalStateException: Connection pool shut down
Now if you want to use HttpClient to call Https Urls and with help of connection pools , you have to add a registry in your connection pool , otherwise it will ignore your SSLContext configurations , and give following error .

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
... 80 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 86 more

package com.javaroots;
import java.io.IOException;
import java.net.URI;
import javax.ws.rs.core.MediaType;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
public class ApacheClient {
private static final Logger LOGGER = LoggerFactory.getLogger(ApacheClient.class);
public static void main(String[] args) throws Exception{
CloseableHttpClient apacheClient = HttpClientFactory.getHttpsClient();
CloseableHttpResponse response2 = null;
HttpGet httpPost = new HttpGet("https://mms.nw.ru/");
RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000)
.build();
HttpEntity entity2 = null;
try {
httpPost.setConfig(defaultRequestConfig);
response2 = apacheClient.execute(httpPost);
System.out.println(response2.getStatusLine());
} catch (Exception e) {
LOGGER.error("Error while getting response: ", e);
throw new HttpClientException(e);
} finally {
try {
response2.close();
apacheClient.close();
} catch (Exception e) {
}
}
}
}


Back to Featured Articles on Logo Paperblog

Magazines