snippetjavaCritical
How to use java.net.URLConnection to fire and handle HTTP requests
Viewed 0 times
neturlconnectionhowjavaandusehandlehttprequestsfire
Problem
Use of
That tutorial basically only shows how to fire 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.
So, how can I use
java.net.URLConnection is asked about pretty often here, and the Oracle tutorial is too concise about it.That tutorial basically only shows how to fire 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.
So, how can I use
java.net.URLConnection to fire and handle "advanced" HTTP requests?Solution
First a disclaimer beforehand: the posted code snippets are all basic examples. You'll need to handle trivial
In case you're developing for Android instead of Java, note also that since introduction of API level 28, cleartext HTTP requests are disabled by default. You are encouraged to use
Java 11
In case you're already on Java 11 or newer, then it's good to know that there's next to
Preparing
We first need to know at least the URL and the charset. The parameters are optional and depend on the functional requirements.
The query parameters must be in
The
Firing an HTTP GET request with (optionally) query parameters
It's a trivial task. It's the default request method.
Any query string should be concatenated to the URL using
Either way, if the other side is an
For testing purposes, you can print the response body to standard output as below:
Firing an HTTP POST request with query parameters
Setting the
Note: whenever you'd like to submit a HTML form programmatically, don't forget to take the
IOExceptions and RuntimeExceptions like NullPointerException, ArrayIndexOutOfBoundsException and consorts yourself.In case you're developing for Android instead of Java, note also that since introduction of API level 28, cleartext HTTP requests are disabled by default. You are encouraged to use
HttpsURLConnection. When really necessary, cleartext can be enabled in the Application Manifest.Java 11
In case you're already on Java 11 or newer, then it's good to know that there's next to
java.net.URLConnection another API to deal with HTTP requests in a less verbose manner: java.net.http.HttpClient.Preparing
We first need to know at least the URL and the charset. The parameters are optional and depend 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 be concatenated by &. You would normally also URL-encode the query parameters with the specified charset using URLEncoder#encode().The
String#format() is just for convenience. I prefer it when I would need the String concatenation operator + more than twice.Firing an HTTP GET request with (optionally) query parameters
It's a trivial task. It's 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);
}Firing an HTTP POST request with query parameters
Setting the
URLConnection#setDoOutput() to true implicitly sets the request method to POST. The standard HTTP POST as web forms do is of type application/x-www-form-urlencoded wherein 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: whenever you'd like to submit a HTML form programmatically, don't forget to take the
name=value pairs of any ` elements into the query string and of course also the name=value pair of the element which you'd like to "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().
Actually firing the HTTP request
You can fire the HTTP request explicitly with URLConnection#connect(), but the request will automatically be fired on demand when you want to get any information about the HTTP response, such as the response body using URLConnection#getInputStream() and so on. The above examples does exactly that, so the connect() call is in fact superfluous.
Timeouts
You can use URLConnection#setConnectTimeout() to set the connect timeout and URLConnection#setReadTimeout() to set the read timeout.
The default is basically "no timeout". So you'd like to set these yourself. For example:
httpConnection.setConnectTimeouCode Snippets
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));URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...InputStream response = new URL(url).openStream();
// ...try (Scanner scanner = new Scanner(response)) {
String responseBody = scanner.useDelimiter("\\A").next();
System.out.println(responseBody);
}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();
// ...Context
Stack Overflow Q#2793150, score: 2847
Revisions (0)
No revisions yet.