Signup/Sign In

HTTP Requests in Java

HttpURLConnection class is part of the java.net package, and it is used to send HTTP requests and fetch responses. It is an abstract class and extends the URLConnection class. This class provides basic functionalities. It is better to use other HTTP libraries for advanced features. In this tutorial, we will learn how to use this class to deal with HTTP requests.

Creating a Request using HttpURLConnection

To get an instance of the HttpURLConnection class, we need to use the openConnection() method on the URL. An explicit cast is also required.

We can set the type of request by using setRequestMethod() on the HttpURLConnection object. It can take one of the following values, and the default is GET.

  • GET
  • POST
  • HEAD
  • OPTIONS
  • PUT
  • DELETE
  • TRACE
import java.net.*;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.studytonight.com");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
	}
}

Adding Request Parameters

We can add request or query parameters to our HTTP request. We first need to enable writing on the connection object by using the setDoOutput() method. We can then get the DataOutputStream and write strings to it. The string must be of the format "param1=val1&param2=val2&param3=val3".

import java.net.*;
import java.io.*;
public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.demo.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");

		connection.setDoOutput(true);
		String parameter = "param1=val1&param2=val2";
		
		DataOutputStream outputStream = (DataOutputStream)connection.getOutputStream();
		outputStream.writeChars(parameter);
		outputStream.flush();
		outputStream.close();
	}
}

We can simplify our work by writing a method that takes a HashMap and generates the parameter-value string from the key-value pairs of the map.

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

public class Demo
{
	public static String addParameters(HashMap<String, String> parameters) throws Exception
	{
		StringBuilder sb = new StringBuilder();		
		for(Map.Entry<String, String> e : parameters.entrySet())
		{
			sb.append(URLEncoder.encode(e.getKey(), "UTF-8"));
			sb.append("=");
			sb.append(URLEncoder.encode(e.getValue(), "UTF-8"));
			sb.append("&");
		}		
		String params = sb.toString();
		if(params.length() > 0)
			return params.substring(0, params.length() - 1);
		else
			return params;
	}
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.demo.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		connection.setDoOutput(true);
		HashMap<String, String> parameters = new HashMap<>();
		parameters.put("param1", "val1");
		parameters.put("param2", "val2");
		parameters.put("param3", "val3");
		
		String params = addParameters(parameters);
		
		DataOutputStream outputStream = (DataOutputStream)connection.getOutputStream();
		outputStream.writeChars(params);
		outputStream.flush();
		outputStream.close();
	}
}

Reading Request Headers

To read the values of the request headers, we use the getHeaderField() method on the connection object. This method can take the name of the header field as a parameter and returns the corresponding value.

import java.net.*;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.studytonight.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		String date = connection.getHeaderField("Date");
		System.out.print(date);
	}
}


Fri, 06 Aug 2021 02:52:29 GMT

We can also use an integer that will fetch the nth header field. Use the getHeaderFieldKey() method to get the name of the nth header field.

import java.net.*;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.studytonight.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		String headerKey1 = connection.getHeaderFieldKey(1);
		String headerField1 = connection.getHeaderField(1);
        
       	String headerKey2 = connection.getHeaderFieldKey(2);
		String headerField2 = connection.getHeaderField(2);
		
		System.out.println("Header Field 1: " + headerKey1 + "-->" + headerField1);
		System.out.println("Header Field 2: " + headerKey2 + "-->" + headerField2);
	}
}


Header Field 1: Date-->Fri, 06 Aug 2021 02:52:29 GMT
Header Field 2: Server-->Apache/2.4.46 (Unix) OpenSSL/1.1.1d

Setting Request Headers

We can use the setRequestProperty() method on the HttpURLConnection instance to set the request header values. Let's set the value for the Connection and the Cache-Control headers.

import java.net.*;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.studytonight.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");

		connection.setRequestProperty("Connection", "Keep-Alive");
		connection.setRequestProperty("Cache-Control", "no-cache");
	}
}

Setting Timeouts

We can use the setConnectTimeout() and setReadTimeout() methods of the HttpURLConnection class to change the default timeout values for connecting and reading. We can view these values by using the getConnectTimeout() and getReadTimeout() methods.

import java.net.*;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.studytonight.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		System.out.println("Default Timeout Values:");
		System.out.println("Connect Timeout: " + connection.getConnectTimeout());
		System.out.println("Read Timeout: " + connection.getReadTimeout());
		
		connection.setConnectTimeout(10000);
		connection.setReadTimeout(10000);
		//After
		System.out.println("After Setting Timeout Values:");
		System.out.println("Connect Timeout: " + connection.getConnectTimeout());
		System.out.println("Read Timeout: " + connection.getReadTimeout());
	}
}


Default Timeout Values:
Connect Timeout: 0
Read Timeout: 0
After Setting Timeout Values:
Connect Timeout: 10000
Read Timeout: 10000

Dealing with Cookies

The HttpCookie and CookieManager classes can help us in working with cookies. To read cookies, we can fetch the value of the Set-Cookie header and parse it using the parse() method of HttpCookie class.

import java.net.*;
import java.util.*;
import org.apache.commons.lang3.StringUtils;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.gmail.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		String  cookieHeaderField = connection.getHeaderField("Set-Cookie");
		List<HttpCookie> cookiesList = HttpCookie.parse(cookieHeaderField);
		
		System.out.println(cookieHeaderField);
		System.out.println(cookiesList);		
	}
}


__Host-GAPS=1:WoZoYd84Dr89KgUX6-xfHQcJX0PpqA:KS--fe4IJ1W4rGiM;Path=/;Expires=Sun, 06-Aug-2023 06:23:56 GMT;Secure;HttpOnly;Priority=HIGH
[__Host-GAPS=1:WoZoYd84Dr89KgUX6-xfHQcJX0PpqA:KS--fe4IJ1W4rGiM]

We can also add cookies to a CookieStore. We can use the CookieStore to set the Cookie request property of the connection. We need to close and reopen our connection to do so.

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.gmail.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		String  cookieHeaderField = connection.getHeaderField("Set-Cookie");
		List<HttpCookie> cookiesList = HttpCookie.parse(cookieHeaderField);

		CookieManager cm = new CookieManager();
		cookiesList.forEach(cookie -> cm.getCookieStore().add(null, cookie));
		
		connection.disconnect();
		connection = (HttpURLConnection) url.openConnection();
		connection.setRequestProperty("Cookie", 
		StringUtils.join(cm.getCookieStore().getCookies(), ";"));
	}
}

Dealing with Redirects

We can use the setInstanceFollowRedirects() method on the HttpURLConnection instance to enable or disable redirect.

import java.net.*;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.google.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		connection.setInstanceFollowRedirects(true);
	}
}

We can also enable or disable redirects for all connections by using the setFollowRedirects() method.

HttpURLConnection.setFollowRedirects(true);

We can use the Location header field to get the new redirect URL. We can use this to send requests to the new redirect URL. Note that the response code for redirects is 301(moved permanently) or 302(temporary redirect).

import java.net.*;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.google.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");		
		boolean redirect = false;		
		if(connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP || connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM)
			redirect = true;		
		if(redirect)
		{
			String redirectURL = connection.getHeaderField("Location");
			URL newURL = new URL(redirectURL);
			connection = (HttpURLConnection) newURL.openConnection();
		}
	}
}

Reading the Response

The HttpURLConnection class provides several methods to read the response to our request.

Reading Response Code and Response Message

We can use the getResponseCode() and the getResponseMessage() methods on the connection instance to read the response code and the response message.

import java.net.*;

public class Demo
{	
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("http://www.google.com");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		int responseCode = connection.getResponseCode();
		String responseMsg = connection.getResponseMessage();
		System.out.print("Response Code: " + responseCode + " Response Message: " + responseMsg);
	}
}


Response Code: 200 Response Message: OK

Reading Response Headers

We can access individual header fields by using the getHeaderField() method. We can fetch all the headers by using the getHeaderFields() method. It will return a map collection. Each key in the map denotes the header field, and the corresponding values are stored in a list.

import java.net.*;
import java.util.List;
import java.util.Map;

public class Demo
{
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("https://www.studytonight.com/");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");

		Map<String, List<String>> headerFields = connection.getHeaderFields();
		
		for(Map.Entry<String, List<String>> e : headerFields.entrySet())
			System.out.println(e.getKey() + "-->" + e.getValue());
	}
}


Transfer-Encoding-->[chunked]
Keep-Alive-->[timeout=5, max=100]
null-->[HTTP/1.1 200 OK]
Server-->[Apache/2.4.46 (Unix) OpenSSL/1.1.1d]
X-Content-Type-Options-->[nosniff]
Connection-->[Keep-Alive]
Pragma-->[no-cache]
Date-->[Fri, 06 Aug 2021 03:40:26 GMT]
Referrer-Policy-->[same-origin]
X-Frame-Options-->[SAMEORIGIN]
Strict-Transport-Security-->[max-age=31536000; includeSubDomains; preload]
Cache-Control-->[no-store, no-cache, must-revalidate]
Vary-->[Accept-Encoding]
Set-Cookie-->[PHPSESSID=8iqquicvn5ada6cjb1ktkbjlcg; path=/]
Expires-->[Thu, 19 Nov 1981 08:52:00 GMT]
X-XSS-Protection-->[1; mode=block]
Content-Type-->[text/html; charset=UTF-8]
X-Powered-By-->[PHP/7.4.15]

Reading Response Content

We can read the response content with the help of the InputStream of the HttpURLConnection object. If the response code is greater than 200, then we will use the getErrorStream() method. Otherwise, use the getInputStream() method. We will wrap the InputStreamReader with a BufferedReader.

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

public class Demo
{	
	public static void main(String[] args) throws Exception
	{
		URL url = new URL("http://www.google.com");
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		
		InputStreamReader isr;
		if(connection.getResponseCode() > 299)
			isr = new InputStreamReader(connection.getErrorStream());
		else
			isr = new InputStreamReader(connection.getInputStream());
		
		BufferedReader br = new BufferedReader(isr);
		
		String line;
		while ((line = br.readLine()) != null)
		    System.out.println(line);
	}
}

Summary

The HttpURLConnection class is very frequently used to work with HTTP requests. This class is part of the java.net package and extends the URLConnection class. In this tutorial, we learned the basics of this class. We learned how to create a connection from a URL. We learned how to set different properties and header values. We also learned how to read the response status, response header, and response content.



About the author:
I am a 3rd-year Computer Science Engineering student at Vellore Institute of Technology. I like to play around with new technologies and love to code.