Apache foundation provides an HttpClient library which is used for sending http requests from java program.
Sending GET and POST requests with HttpClient library is pretty easy.
This article will explain how to use HttpClient to send http requests as rest calls from java with examples.
For using HttpClient library, first you need to add it to your project.
You can directly download its jar and add it to classpath or if you are using a build tool, then add its dependency as below.
Maven
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
Gradle
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.13'
Following are the steps required for using Apache HttpClient to send requests and receive response.
If you are not interested in the explanation, then directly jump to the example below.
1. Creating HttpClient
In order to execute HTTP requests with HttpClient, first we need to create a client object which can send requests to a remote URL.
In Apache HttpClient, this is done using createDefault()
method of org.apache.http.impl.client.HttpClients
class. This is a static method and returns an instance of CloseableHttpClient
.
CloseableHttpClient httpClient = HttpClients.createDefault();
Many examples in other tutorials are using DefaultHttpClient
to create a client object
DefaultHttpClient c = new DefaultHttpClient();
This method is now deprecated and should not be used.
Second step is to create a request object. This actually also shows the type of request.
Apache HttpClient has different classes for each of request types such as
HttpGet
for GET, HttpPost
for POST, HttpDelete
for DELETE and so on.All these objects accept a string URL to which the request should be sent. Example,
HttpGet get = new HttpGet("http://google.com");
3. Sending request
CloseableHttpClient
has an execute()
method which accepts a request object that we created in the last section.
Simply provide the request object and it will send it to the desired URL as shown below.
CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet get = new HttpGet(<URL>); httpClient.execute(get);
4. Reading response
execute()
method returns an object of type CloseableHttpResponse
. This is a marker interface.
Its implementing class contains returned response but in object format which needs to be converted to a string to be utilized.
There are two ways to convert response object to a string.
A. Reading Inputstream
Object of type CloseableHttpResponse
provides a method getEntity()
, which in turn provides a method getContent()
returning an inputstream
containing the response.
This inputstream can be converted to a string. Example,
CloseableHttpResponse response = closeableHttpClient.execute(get); InputStream inputStream = response.getEntity().getContent(); BufferedReader reader = new BufferedReader(new java.io.InputStreamReader(inputStream)); String responseStr = null; while((responseStr = reader.readLine())!=null) { System.out.println(responseStr); }
B. Using EntityUtils
Object of type CloseableHttpResponse
provides a method getEntity()
, which is an object of type HttpEntity
.
This can be directly converted to a string using org.apache.http.util.EntityUtils
class as shown below.
CloseableHttpResponse response = closeableHttpClient.execute(get); HttpEntity entity = response.getEntity(); String responseStr = EntityUtils.toString(entity);
or in one-liner
CloseableHttpResponse response = closeableHttpClient.execute(get); String responseStr = EntityUtils.toString( response.getEntity() );
Putting all the above steps together, we are ready to execute a GET request with Apache HttpClient.
Complete example follows.
// create client CloseableHttpClient client = HttpClients.createDefault(); // create request object HttpGet get = new HttpGet("http://dummy.restapiexample.com/api/v1/employee/1"); BufferedReader reader = null; try { // send request CloseableHttpResponse response = client.execute(get); // read response InputStream inputStream = response.getEntity().getContent(); reader = new BufferedReader(new java.io.InputStreamReader(inputStream)); String line = null; while((line = reader.readLine())!=null) { System.out.println(line); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(reader != null) { reader.close(); } if(client != null) { client.close(); } }
This example uses a Fake REST API. The response returned is printed below.
{ "status":"success", "data":{ "id":1, "employee_name":"Tiger Nixon", "employee_salary":320800, "employee_age":61, "profile_image":"" }, "message":"Successfully! Record has been fetched." }
Getting Response code
You can also retrieve other details from the response such as the response code, protocol from the response object as shown below.
CloseableHttpResponse response = client.execute(get); System.out.println(response.getStatusLine().getStatusCode()); System.out.println(response.getProtocolVersion()); System.out.println(response.getStatusLine());
which prints
200
HTTP/1.1
HTTP/1.1 200 OK
Getting response headers
Response object has a getHeaders()
method which returns an array of Header objects.
This array can be iterated to get the header information. Example,
CloseableHttpResponse response = closeableHttpClient.execute(get); Header[] allHeaders = response.getAllHeaders(); for (Header header : allHeaders) { System.out.println("Header: "+header.getName()+ ", Value: "+header.getValue()); }
Note that the array is iterated using an enhanced for loop in java.
This prints
Header: Cache-Control, Value: no-cache, private, max-age=31536000
Header: Content-Type, Value: application/json
Header: Date, Value: Tue, 13 Oct 2020 06:31:25 GMT
Header: Display, Value: staticcontent_sol
Header: Expires, Value: Wed, 13 Oct 2021 06:31:24 GMT
Header: Host-Header, Value: c2hhcmVkLmJsdWVob3N0LmNvbQ==
Header: Referrer-Policy, Value:
Header: Response, Value: 200
// other headers truncated
If you want to retrieve a header value from its name, then you can also use getFirstHeader()
, getLastHeader()
and getHeaders()
methods supplying the header name as argument.
Sending a POST request with HttpClient also involves the same steps but with a few modifications.
1. You need to create an object of
HttpPost
that represents the request.2. If there are some parameters that need to be sent as the body of the request, then those also need to be set.
Example follows
// create client CloseableHttpClient client = HttpClients.createDefault(); // create request object HttpPost post = new HttpPost("https://jsonplaceholder.typicode.com/posts"); try { List params = new ArrayList<>(); params.add(new BasicNameValuePair("userId", "1")); params.add(new BasicNameValuePair("title", "Dummy title")); params.add(new BasicNameValuePair("body", "Dummy body")); post.setEntity(new UrlEncodedFormEntity(params)); // send request CloseableHttpResponse response = client.execute(post); // read response String responseStr = EntityUtils.toString(response.getEntity()); System.out.println(responseStr); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(client != null) { client.close(); } }
Parameters that need to be sent as a part of request body are sent in the form of name-value pairs.
For creating a name-value pair, create an object of type BasicNameValuePair
using its constructor that takes name and value as arguments.
Add all the name-value pairs to a List and add this list to request object using its setEntity()
method.
POST request is then sent using execute()
method of CloseableHttpClient
.
Below is the response
{
“userId”: “1”,
“title”: “Dummy title”,
“body”: “Dummy body”,
“id”: 101
}
This shows that a record with id 101 was created on the server.
HttpClient POST JSON example
You might want to send JSON data to the REST end point since it might be a Spring controller which is expecting a java object.
With HttpClient, you can send a JSON string as shown below.
// create client CloseableHttpClient client = HttpClients.createDefault(); // create request object HttpPost post = new HttpPost("https://jsonplaceholder.typicode.com/posts"); try { String json = "{\"userId\":1,\"body\":\"Dummy\"}"; StringEntity entity = new StringEntity(json); post.setEntity(new UrlEncodedFormEntity(params)); // send request CloseableHttpResponse response = client.execute(post); // read response String responseStr = EntityUtils.toString(response.getEntity()); System.out.println(responseStr); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(client != null) { client.close(); } }
Only difference is that you need to create an object of StringEntity
supplying it the JSON string.
This entity can then be set into request object using setEntity()
method just like we did in earlier example.
Sending object in POST
You might have a java object that you want to send as POST request body.
This object needs to be converted to a JSON String and then it can be sent in the same way as shown in last example.
Jackson’s ObjectMapper
can be used to convert an object to a JSON string as shown below.
HttpPost post = new HttpPost("https://jsonplaceholder.typicode.com/posts"); // create object to send in body Post postObj = new Post(); // set values postObj.setBody("Dummy body"); postObj.setUserId(1); postObj.setTitle("Dummy Title"); // convert it to JSON string ObjectMapper mapper = new ObjectMapper(); String objectStr = mapper.writeValueAsString(postObj); StringEntity entity = new StringEntity(objectStr); // set it in request post.setEntity(entity);
You can also convert an object to a JSON string by appending its properties and values together in a valid JSON format.
But this approach is not recommended for larger objects since it would require multiple string operations and it is error prone.
Hope the article was helpful.