-1

I need to make a GET request to a user supplied URL (which could be either http or https)

In JavaScript I could do:

fetch(prompt()).then(r => r.text()).then(console.log)

What is the equivalent code for Java?

How does this work with a custom certificate?

dan1st
  • 12,568
  • 8
  • 34
  • 67
Lebster
  • 289
  • 5
  • 12
  • 2
    Does this answer your question? [How to execute a https GET request from java](https://stackoverflow.com/questions/26393031/how-to-execute-a-https-get-request-from-java) – SRJ Feb 17 '21 at 05:45

2 Answers2

3

URL/URLConnection

Java is fundamentally different than js.

One of these differences is that java is blocking/synchronous meaning the default way is to wait for the request:

known/trusted certificate or HTTP

final URL url=new URL("url here");//create url
//Open an InputStream (binary) to the URL
//Convert it to a reader(text)
//Use buffering
try(BufferedReader br=new BufferedReader (new InputStreamReader(url.openStream(),StandardCharsets.UTF_8))){
    br.lines().forEach(System.out::println);//print all lines
}catch(IOException e){
    //Error handling
}

The try-with-resources statement closes the resources automatically when they are not needed any more.

This is important to do this so you don't have resource leaks.

Self signed/custom certificate

As stated in this answer, you can configure a TrustStore in order to add a custom certificate:

//Load certificate
File crtFile = new File("server.crt");
Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("server", certificate);

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

final URL url=new URL("url here");//create url

HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();//open a connection
connection.setSSLSocketFactory(sslContext.getSocketFactory());

//Open an InputStream (binary) to the URL
//Convert it to a reader(text)
//Use buffering
try(BufferedReader br=new BufferedReader (new InputStreamReader(connection.getInputStream(),StandardCharsets.UTF_8))){
    br.lines().forEach(System.out::println);//print all lines
}catch(IOException e){
    //Error handling
}


HttpClient

If you use Java 11 or newer, you could also try to use the asynchronous HttpClient as described here.

This is more similar to the JS approach.

known/trusted certificate or HTTP

HttpClient client = HttpClient.newHttpClient();//create the HTTPClient
HttpRequest request = HttpRequest.newBuilder()//create a request object, GET is the default
      .uri(URI.create("url here"))//set the url
      .build();//build the request object
client.sendAsync(request, BodyHandlers.ofString())//send the request in a background thread (fetch() in your code)
      .thenApply(HttpResponse::body)//get the body as a string (.then(r=>r.text()) in your code))
      .thenAccept(System.out::println);//print it (.then(console.log) in your code)

This approach is asynchronous like your JS example.

Self signed/custom certificate

If you want to use custom certificates, you can use the sslContect method like here:

//Load certificate
File crtFile = new File("server.crt");
Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("server", certificate);

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

//Execute the request
HttpClient client = HttpClient.newBuilder()//create a builder for the HttpClient
    .sslContext(sslContext)//set the SSL context
    .build();//build the HttpClient
HttpRequest request = HttpRequest.newBuilder()//create a request object, GET is the default
      .uri(URI.create("url here"))//set the url
      .build();//build the request object
client.sendAsync(request, BodyHandlers.ofString())//send the request in a background thread (fetch() in your code)
      .thenApply(HttpResponse::body)//get the body as a string (.then(r=>r.text()) in your code))
      .thenAccept(System.out::println);//print it (.then(console.log) in your code)

external library

The third possibility is to use an external library like OkHttp.

dan1st
  • 12,568
  • 8
  • 34
  • 67
  • 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 – Lebster Feb 17 '21 at 06:03
  • The JavaScript code was just an example to demonstrate what I want to do – Lebster Feb 17 '21 at 06:04
  • What java version do you use? Do you use an old version of Java 8? What https certification does the server use? Does the Server use Let's Encrypt X3? – dan1st Feb 17 '21 at 06:41
  • As I said in the question, the server certificate is not known because it’s user supplied. I’m using Java 8 – Lebster Feb 17 '21 at 17:22
  • See my edit on how to use custom certificates. – dan1st Feb 17 '21 at 18:25
  • Oh my goodness, thank you so much! The TrustStore method worked for me! – Lebster Feb 17 '21 at 18:26
  • It was a bit unclear that the certificate is self-signed. – dan1st Feb 17 '21 at 18:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/228862/discussion-between-lebster-and-dan1st). – Lebster Feb 17 '21 at 18:29
0

HttpURLConnection class from java.net package can be used to send Java HTTP Request programmatically. Today we will learn how to use HttpURLConnection in java program to send GET and POST requests and then print the response.

Below are the steps we need to follow for sending Java HTTP requests using HttpURLConnection class.

  1. Create URL object from the GET/POST URL String.
  2. Call openConnection() method on URL object that returns instance of HttpURLConnection
  3. Set the request method in HttpURLConnection instance, default value is GET.
  4. Call setRequestProperty() method on HttpURLConnection instance to set request header values, such as “User-Agent” and “Accept-Language” etc.
  5. We can call getResponseCode() to get the response HTTP code. This way we know if the request was processed successfully or there was any HTTP error message thrown.
  6. For GET, we can simply use Reader and InputStream to read the response and process it accordingly.
  7. For POST, before we read response we need to get the OutputStream from HttpURLConnection instance and write POST parameters into it.

HttpURLConnection Example

Based on the above steps, below is the example program showing usage of HttpURLConnection to send Java GET and POST requests.

JAVA CODE

package com.mr.rockerz.HttpUrlExample;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpURLConnectionExample {

    private static final String USER_AGENT = "Mozilla/5.0";

    private static final String GET_URL = "https://localhost:9090/SpringMVCExample";

    private static final String POST_URL = "https://localhost:9090/SpringMVCExample/home";

    private static final String POST_PARAMS = "userName=Pankaj";

    public static void main(String[] args) throws IOException {

        sendGET();
        System.out.println("GET DONE");
        sendPOST();
        System.out.println("POST DONE");
    }

    private static void sendGET() throws IOException {
        URL obj = new URL(GET_URL);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", USER_AGENT);
        int responseCode = con.getResponseCode();
        System.out.println("GET Response Code :: " + responseCode);
        if (responseCode == HttpURLConnection.HTTP_OK) { // success
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // print result
            System.out.println(response.toString());
        } else {
            System.out.println("GET request not worked");
        }

    }

    private static void sendPOST() throws IOException {
        URL obj = new URL(POST_URL);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", USER_AGENT);

        // For POST only - START
        con.setDoOutput(true);
        OutputStream os = con.getOutputStream();
        os.write(POST_PARAMS.getBytes());
        os.flush();
        os.close();
        // For POST only - END

        int responseCode = con.getResponseCode();
        System.out.println("POST Response Code :: " + responseCode);

        if (responseCode == HttpURLConnection.HTTP_OK) { //success
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // print result
            System.out.println(response.toString());
        } else {
            System.out.println("POST request not worked");
        }
    }

}

When we execute the above program, we get below response.

GET Response Code :: 200
<html><head>    <title>Home</title></head><body><h1>    Hello world!  </h1><P>  The time on the server is March 6, 2015 9:31:04 PM IST. </P></body></html>
GET DONE
POST Response Code :: 200
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>User Home Page</title></head><body><h3>Hi Pankaj</h3></body></html>
POST DONE

If You have Any Doubts ask in Comment.

Sanjith
  • 49
  • 3