Monday 13 February 2017

Textual Representation of logo

How to use Apache HttpClient 4.5 for Https Connections

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) {

   }

  }
 }



}