Apache HttpClient4 with Spring
In this tutorial we'll have a good look at the Apache HttpClient4 library like and cover subjects like:
- Get & validate the status code of the HTTP response
- Configure timeout
- Cancel/Abort a request
- Set Hard Timeout
- Set custom header
Designed as an extension while providing complete support for the base HTTP protocol, HttpClient may be of use to anyone making HTTP-aware client applications such as web browsers, web service clients, or systems that use or extend the HTTP protocol for personalised web apps.
Features
This HTTP client library provides an extensive list of features including:
- Pure Java implementation
- Complete implementation of all HTTP methods like GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE in OO form
- Supports encryption with HTTPS (HTTP over SSL) protocol
- Supports response caching
- Configurable timeout
- Source code is freely available under the Apache License
Maven Dependency
To start, we need to add the corresponding Maven dependencies to our project for HttpClient 4. For this, we need the httpclient maven dependency as shown:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
</dependency>
To get the latest dependency version, check here.
Get a Status Code from HTTP response
After we send a request, we get back an instance of org.apache.http.HttpResponse – which allows us to access the status line of the response, and specifically the Status Code:
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(new HttpGet(MY_URL));
int statusCode = response.getStatusLine().getStatusCode();
It is worth noticing that there are predefined Status Codes available in the library via org.apache.http.HttpStatus. To see the list of all available HTTP status codes, see here.
Configure Timeout
Configuring a Timeout in HttpClient is easy and there is more than one way this can be done. Let us have a look at each of these one by one and also look at some terms beforehand:
- the Connection Timeout (http.connection.timeout) – the time to establish the connection with the remote host
- the Socket Timeout (http.socket.timeout) - the time waiting for data, after the connection was established; maximum time of inactivity between two data packets
Via Type Safe API
A better way is to use a type-safe API. Let’s look at an example directly:
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
int timeout = 5; // seconds
HttpParams httpParams = defaultHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(
httpParams, timeout * 1000); // http.connection.timeout
HttpConnectionParams.setSoTimeout(
httpParams, timeout * 1000); // http.socket.timeout
Via Raw String parameters
Just to be clear, HttpClient has a lot of parameters that can be configured which can be set in key-value pairs.
DefaultHttpClient httpClient = new DefaultHttpClient();
int timeout = 5; // seconds
HttpParams httpParams = httpClient.getParams();
httpParams.setParameter(
CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000);
httpParams.setParameter(
CoreConnectionPNames.SO_TIMEOUT, timeout * 1000);
Clearly, this method above is a little difficult and can cause typos.
Via new Builder
The elegant, builder API introduced in HttpClient 4.3 provides the correct way to set timeouts at a high level:
int timeout = 5;
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(timeout * 1000)
.setConnectionRequestTimeout(timeout * 1000)
.setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client =
HttpClientBuilder.create().setDefaultRequestConfig(config).build();
Using the Builder API is the recommended way of configuring in a type-safe and readable manner.
Hard Timeout
When we configure timeouts, we usually set the for request which we know won’t take long to be processed by a server. In many apps however, there exists some services which serve or accept large bits of data like media files etc. which take long to process and for the request to be completed.
Even in these scenario, it is important to set a Hard timeout for the entire request. Clearly, uploading a profile picture for a user should not take anywhere near 60 seconds!
HttpClient doesn’t have any configurable settings that allow us to set an overall timeout for a request; it does, however, provide abort functionality for requests, so we can use that option to implement a simple timeout mechanism:
HttpGet getMethod = new HttpGet(
"http://localhost:8080/common/service/user/1");
int hardTimeout = 15; // seconds
TimerTask outTask = new TimerTask() {
@Override
public void run() {
if (getMethod != null) {
getMethod.abort();
}
}
};
new Timer(true).schedule(outTask, hardTimeout * 1000);
HttpResponse response = httpClient.execute(getMethod);
System.out.println(
"HTTP Status of response: " + response.getStatusLine().getStatusCode());
Here, we make use of TimerTask in Java which will abort this request with a Hard timeout of 15 seconds.
Abort or cancel request
Whenever we want to abort or cancel an HTTP request mid-way, we can simply call abort:
HttpClient instance = HttpClients.custom().build();
HttpGet request = new HttpGet(SAMPLE_URL);
HttpResponse response = instance.execute(request);
try {
System.out.println(response.getStatusLine());
request.abort();
} finally {
response.close();
}
Setting a Custom Header
We can set a custom header on a request with a simple setHeader call:
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(MY_URL);
httpGet.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
client.execute(httpGet);
In the sample above, we set the custom content type for a request as Json.
Default Header for all request
Instead of setting the Header on each request, we can also configure it as a default header on the Client itself:
Header header = new BasicHeader(
HttpHeaders.CONTENT_TYPE, "application/json");
List<Header> headers = Lists.newArrayList(header);
HttpClient client = HttpClients.custom()
.setDefaultHeaders(headers).build();
HttpUriRequest request = RequestBuilder.get()
.setUri(SAMPLE_URL).build();
client.execute(request);
This is particularly important when the header needs to be same for all requests, such as a custom application header like having a token.
Conclusion
In this article, we went through the Apache HttpClient library which is written in pure Java and can be used to make a performant communication link between client and server apps.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment