Explain about URL and HTTPS protocol

1. Resolve a relative URL

import java.net.URL;

public class ResolveRelativeURL {
  public static void main (String[] args) throws
       java.net.MalformedURLException {
    URL relativeURL, baseURL;
    baseURL = new URL ("http://www.maixuanviet.com/");
    relativeURL = new URL ( baseURL, "./javadetails/java-0001.html");
    System.out.println ( relativeURL.toExternalForm ());
    /*
      output :
       http://www.maixuanviet.com/javadetails/java-0001.html
    */    
  }
}

2. File size from URL

import java.io.*;
import java.net.*;

public class FileSizeFromURL {
  public static final void main(String[] args) {
    URL url;
    URLConnection conn;
    int size;

    if(args.length != 1) {
      System.out.println("Usage: FileSizeFromURL ");
      return;
      }

    try {
      url = new URL(args[0]);
      conn = url.openConnection();
      size = conn.getContentLength();
      if(size < 0)
         System.out.println("Could not determine file size.");
      else
        System.out.println(args[0] + "\nSize: " + size);
      conn.getInputStream().close();
      } 
    catch(Exception e) {
      e.printStackTrace();
      }
    }
}

3. Use the HTTPS protocol

For Applets, both IE and NN have implemented https in their java.net.URL class so just use it exactly as you would for a regular http URL.

URL ssl = new URL("https://www.secureserver.com);
InputStream is = ssl.openStream();

For application, take a look at the Sun’s Secure Socket Extension (JSSE).

Before connecting with a secure URL, we must do this first:

java.security.Security.addProvider(new
   com.sun.net.ssl.internal.ssl.Provider());

System.setProperty
   ("java.protocol.handler.pkgs",
    "com.sun.net.ssl.internal.www.protocol");

Since JDK 1.4, the JSSE package is included so you don’t have to add anything special. However you may need to import the certificate from the host (that is the server that you are connecting to using the https: protocol). One easy way to do this is to open a secured page (say https://mysecuredhost.com) with IE, click on the SSL-symbol (bottom right) and exported the key into the file “c:\cacerts.ce”. Go in “%java_home%\bin” and type this:

keytool -import -v -alias meincert -trustcacerts -file c:\

4. Fix certificate problem in HTTPS

HTTPS protocol is supported since JDK1.4 (AFAIK), you have nothing special to do.

import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;

public class ConnectHttps {
  public static void main(String[] args) throws Exception {
    URL url = new URL("https://www.maixuanviet.com/howto.html");
    URLConnection con = url.openConnection();
    Reader reader = new InputStreamReader(con.getInputStream());
    while (true) {
      int ch = reader.read();
      if (ch==-1) {
        break;
      }
      System.out.print((char)ch);
    }
  }
}

However, you can have a problem if the server certificate is self-signed by a testing certification authority (CA) which is not in trusted CAs of Java on the client side. An exception like is thrown. This is a common situation with a development server.

Exception in thread "main" 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

The fix is to add the self signed certificate to trusted CAs on the client side. You do that by updating the CACERT file in the your JRE_HOME/lib directory.

Export the certificate from your web browser.

In Google Chrome, open the endpoint url, then press F12, then go to security tab in Developer window.

Click “View Certificate”, go to Details tab, and export to a .cer file (click “Copy to file”, and just follow the wizard using default settings at each step).

Now that you have your .cer file, you need to update the cacerts in your JRE installation. The keytool utility (included in your Java installation) is used to do that.

Open a cmd with admin rights, then navigate to the bin directory of your java installation, and run the following command:

keytool -import -alias myNewCertificate -file "/path/to/mycert.cer" -keystore "\lib\security\cacerts" -storepass changeit

Where /path/to/mycert.cer is the absolute path to your .cer file created in the first step and replace “JRE_HOME” with the path to your java installation (can be something like C:\Program Files\Java\jre1.8.0_131).

Or you can override the check and accept an untrusted certificate (with the risk coming with it! It’s a HACK and should not be used in code in production).

import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class ConnectHttps {
  public static void main(String[] args) throws Exception {
    /*
     *  fix for
     *    Exception in thread "main" 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
     */
    TrustManager[] trustAllCerts = new TrustManager[] {
       new X509TrustManager() {
          public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
          }

          public void checkClientTrusted(X509Certificate[] certs, String authType) {  }

          public void checkServerTrusted(X509Certificate[] certs, String authType) {  }

       }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
          return true;
        }
    };
    // Install the all-trusting host verifier
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    /*
     * end of the fix
     */

    URL url = new URL("https://securewebsitewithuntrustedcertificate.com");
    URLConnection con = url.openConnection();
    Reader reader = new InputStreamReader(con.getInputStream());
    while (true) {
      int ch = reader.read();
      if (ch==-1) {
        break;
      }
      System.out.print((char)ch);
    }
  }
}

Done! Happy Coding!