Accommodate HTTPS Connections

Topic containing commented Java code for this example: HttpURLConnectionTechnique.java.

Note: To connect through HTTPS, you have to handle authentication. In all likelihood, a hosted Infinity application uses Basic authentication. For information about how to handle Basic authentication in your Java client, see Basic Authentication with Java. For a broader discussion about authentication and authorization with Infinity applications, see Authentication and Authorization.

HttpsURLConnection inherits the properties of HttpURLConnection. So to work with secure HTTP connections, you can adjust the connection code to use that class. For HTTP, we had:

        URL urlForInfWebSvc = new URL(urlString);
        URLConnection UrlConnInfWebSvc = urlForInfWebSvc.openConnection();
        HttpURLConnection httpUrlConnInfWebSvc = (HttpURLConnection) UrlConnInfWebSvc;

For HTTPS, we can adjust it to:

        URL urlForInfWebSvc = new URL(urlString);
        URLConnection UrlConnInfWebSvc = urlForInfWebSvc.openConnection();
        HttpsURLConnection httpUrlConnInfWebSvc = (HttpsURLConnection) UrlConnInfWebSvc;

Are there any other complications? Possibly. But for now, lets assume that this is what we need to accommodate an endpoint URL that uses HTTPS. Of course, we may want the program to make the determination as to which type of connection is necessary. So let's put connection creation into its own class and add a test for whether the endpoint is HTTP or HTTPS. To do this, we need to separate finding the URL string from the logic that creates the connection objects. So we will add a String parameter for the constructor that passes the URL string.

We want the connection to send a request and receive a reply. Now, ideally, we would handle persisting the connection. But to avoid complications, we'll just create a method that takes a SOAP request message along with the URL string and returns the SOAP response as a String. Creating the connection and disconnecting will happen in this method. We'll also create a method to perform the test and a method to extract the host name from the endpoint String.

Here is the method to check the URL string:

    public static Boolean connectionIsHttps (String urlString){
        if (urlString.regionMatches(0, "https", 0, 5)){
            return true;
        }
        else {
            return false;
        }  
    }

This is a simple implementation. You could also do some validity checks and exception handling here for bad URL strings. But for now, this works. It returns true if the URL string begins with https and returns false otherwise.

Here is a method to extract the host name from the URL string:

    public static String getHostNameFromUrl (String urlString){
        if (connectionIsHttps(urlString)){
            return urlString.substring(8,urlString.indexOf("/", 8));
        }
        else{
            return urlString.substring(7,urlString.indexOf("/", 7));
        }
    }

This checks whether the URL string begins with https using the connectionIsHttps method we created. Then based on that, it returns the substring between http:// or https:// and the next occurrence of /.

To create the connection based on whether the URL string is https, we'll check for the condition and perform almost the same logic for https versus http. The main difference is that we will declare an object of type HttpsURLConnection in one case and HttpURLConnection in the other. Since we pass the SOAP message and URL string, there is no hard-coded SOAP message as in Create Connections with URLConnection.

    public static String createHttpURLConnectionAndMakeRequest
            (String soapMessage, String urlString)
            throws MalformedURLException, FileNotFoundException, IOException{
        
        String lvSoapMessage = soapMessage;
        String responseString = "";
        //Create connection
        URL URLForSOAP = new URL(urlString);
        URLConnection URLConnectionForSOAP = URLForSOAP.openConnection();
        if (connectionIsHttps(urlString)) {
            HttpsURLConnection Connection =
                    (HttpsURLConnection) URLConnectionForSOAP;
            //Adjust connection
            Connection.setDoOutput(true);
            Connection.setDoInput(true);
            Connection.setRequestMethod("POST");
            //Use the method to get the host name from the URL string and set
            //the request property for the connection.
            Connection.setRequestProperty
                    ("Host", getHostNameFromUrl(urlString));
            Connection.setRequestProperty
                    ("Content-Type","application/soap+xml; charset=utf-8");
            //Send the request
            OutputStreamWriter soapRequestWriter =
                    new OutputStreamWriter(Connection.getOutputStream());
            soapRequestWriter.write(lvSoapMessage);
            System.out.println(lvSoapMessage);
            soapRequestWriter.flush();
            //Read the reply
            BufferedReader soapRequestReader =
                    new BufferedReader
                            (new InputStreamReader
                                    (Connection.getInputStream()));
            String line;
            while ((line = soapRequestReader.readLine()) != null) {
                responseString = responseString.concat(line);
                }
            //Clean up
            soapRequestWriter.close();
            soapRequestReader.close();
            Connection.disconnect();
        }
        else{
            //See comments for https case above.
            HttpURLConnection Connection =
                    (HttpURLConnection) URLConnectionForSOAP;
            Connection.setDoOutput(true);
            Connection.setDoInput(true);
            Connection.setRequestMethod("POST");
            Connection.setRequestProperty
                    ("Host", getHostNameFromUrl(urlString));
            Connection.setRequestProperty
                    ("Content-Type","application/soap+xml; charset=utf-8");
            OutputStreamWriter soapRequestWriter =
                    new OutputStreamWriter(Connection.getOutputStream());
            soapRequestWriter.write(lvSoapMessage);
            soapRequestWriter.flush();
            BufferedReader soapRequestReader =
                    new BufferedReader
                            (new InputStreamReader
                                    (Connection.getInputStream()));
            String line;
            while ((line = soapRequestReader.readLine()) != null) {
                responseString = responseString.concat(line);
                }
            soapRequestWriter.close();
            soapRequestReader.close();
            Connection.disconnect();
        }
        
        return responseString;
    }