How to use java.net.URLConnection to send and handle HTTP requests
In this blog, we are going to learn about the Use of java.net.URLConnection is asked about pretty often here, and the Oracle tutorial is pretty clear about this and shows how to send a GET request and read the response. It doesn’t explain anywhere how to use it to, among others, perform a POST request, set request headers, read response headers, deal with cookies, submit a HTML form, upload a file, etc.
Firstly, We need to know the URL and charset. The parameters are optional and depends on the functional requirements.
String url = "http://example.com";
String charset = "UTF-8"; // Or in Java 7 and later, use the constant: java.nio.charset.StandardCharsets.UTF_8.name()
String param1 = "value1";
String param2 = "value2";
// ...
String query = String.format("param1=%s¶m2=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(param2, charset));
The query parameters must be in name=value format and concatenated by & and you can also URL-encode the query parameters with the specified charset using URLEncoder#encode().
The String#format() is for convenience. Instead we need to use the String concatenation operator + more than twice.
Sending a HTTP POST request with query parameters
Setting the URLConnection#setDoOutput() to true sets the request method to POST. The standard HTTP POST as web forms do is of type application/x-www-form-urlencoded where the query string is written to the request body.
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
try (OutputStream output = connection.getOutputStream()) {
output.write(query.getBytes(charset));
}
InputStream response = connection.getInputStream();
// ...
Note: When you submit a HTML form programmatically, don’t forget to take the name=value pairs of any elements into the query string and also the name=value pair of the element which you “press” programmatically (because that’s usually been used in the server side to distinguish if a button was pressed and if so, which one).
You can also cast the obtained URLConnection to HttpURLConnection and use its HttpURLConnection#setRequestMethod() instead. But if you’re trying to use the connection for output you still need to set URLConnection#setDoOutput() to true.
HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...
Either way, if the other side is an HttpServlet, then its doPost() method will be called and the parameters will be available by HttpServletRequest#getParameter().
Sending a HTTP GET request with (optionally) query parameters
It is the default request method.
URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...
Any query string should be concatenated to the URL using ?. The Accept-Charset header may hint the server what encoding the parameters are in. If you don’t send any query string, then you can leave the Accept-Charset header away. If you don’t need to set any headers, then you can even use the URL#openStream() shortcut method.
InputStream response = new URL(url).openStream();
// ...
Either way, if the other side is an HttpServlet, then its doGet() method will be called and the parameters will be available by HttpServletRequest#getParameter().
For testing purposes, you can print the response body to standard output as below:
try (Scanner scanner = new Scanner(response)) {
String responseBody = scanner.useDelimiter("\\A").next();
System.out.println(responseBody);
}