Using HTTPS GET/POST – Commons HttpClient with Self Signed Certificate

I think Commons HTTPClient is a quite useful open source library for accessing various HTTP APIs from Java back end. It is very easy to setup a quick test program using this library. I used this very recently when one of our clients requested quick HTTPS access on one of his servers and we had to enable that using self-signed certificate(how to to enable SSL on apache using a self-signed certificate?) . If you want to learn more about HTTPS and SSL you can get some information here

As customer wanted to try some of the HTTP APIs which are exposed by the product and wanted to access them securely, We did a quick test for him that how he can access these APIs from Java. I had already access these HTTP GET/POST APIs several times using Commons HTTPClient, and some other HTTPS APIs as well but with self-signed certificate, I was aware that JSSE will not handle by default. As I tried to run the test program it failed and gave following error:

HttpClient client = new HttpClient();
byte[] response = null;
PostMethod method = new PostMethod("https://server_address/servlet_path");

method.addParameter("param1", "value1");
method.addParameter("param2", "value2");
try{
	int statusCode = client.executeMethod(method);

	if (statusCode != HttpStatus.SC_OK) {
		throw new Exception("Error code : " + statusCode);
	}
	response = method.getResponseBody();
}catch(Exception e){
	System.out.println(e.getMessage());
}
System.out.println(new String(response));
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Exception in thread "main" java.lang.NullPointerException
	at java.lang.String.<init>(Unknown Source)
	at APITest.main(PortalLicenseGenerator.java:40)

Had some more research and learnt that some customizations are required to make HTTPClient work with Self signed certificate. below is the final code with worked well:

Protocol myhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost("server_address",443,myhttps);
byte[] response = null;
PostMethod method = new PostMethod("/servlet_path");

method.addParameter("param1", "value1");
method.addParameter("param2", "value2");
try{
	int statusCode = client.executeMethod(method);

	if (statusCode != HttpStatus.SC_OK) {
		throw new Exception("Error code : " + statusCode);
	}
	response = method.getResponseBody();
}catch(Exception e){
	System.out.println(e.getMessage());
}
System.out.println(new String(response));

EasySSLProtocolSocketFactory can be found at org.apache.commons.httpclient.contrib.ssl which is generally not given with the distribution package so you need to download it from source control (subversion). Get more classes accordingly, in case you face compilation errors.

Most Commented Posts

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

No comments yet.

Leave a comment

(required)

(required)