Getting markup from HTTPS connection in Java program

One of the common requirements in J2EE is making a request to HTTP URL and getting response back. The JDK has support to make HTTP call and get response, you dont have to use any external library if you dont want to but (But most of us use Apache HTTP Client).

This sample code demonstrates how you can make a HTTP call to http://wpconnections1.atech.com/ and get and print response back to the console


package com.webspherenotes.ssl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HelloSSL {
public static void main(String[] args) {
try {
URL url = new URL("http://wpconnections1.atech.com/");

// Open the URL: throws exception if not found
HttpURLConnection conn =
(HttpURLConnection)url.openConnection();
conn.connect();
InputStream inputStream = conn.getInputStream();
BufferedReader reader =
new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line = reader.readLine()) != null){
System.out.println(line);
}
} catch (MalformedURLException e) {
e.printStackTrace(System.out);
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
}



This program works but you might want to access the same URL on HTTPs instead of HTTP, This program will work if you try to access say https://encrypted.google.com. But, In development environment we use self-signed SSL certificate and your JVM would not trust the self-signed SSL certificate. So when you try to connect to http://wpconnections1.atech.com/ it will throw this exception


javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
at com.webspherenotes.ssl.HelloSSL.main(HelloSSL.java:23)
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(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid
certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 18 more


You will have to follow some additional steps to import the self signed SSL certificate in your JVM so that it trust it. There are multiple ways to do that but the one that i like is outlined here http://blogs.sun.com/andreas/entry/no_more_unable_to_find, first i had to download the InstallCert.java on my machine and package it into a .jar file then i executed


java -jar InstallCert.jar wpconnections1.atech.com


This will create a jssecacert file on your machine where you executed the InstallCert.jar. In my case i did execute the .jar in c:\temp so i did create a C:\Temp\jssecacert file in that directory. This file has the imported certificate for wpconnections1.atech.com

Then i went back to my program and i did execute it by adding following JVM argument -Djavax.net.ssl.trustStore="c:\temp\jssecacerts" like this


Now when i run the HelloSSL program i can see response being returned