This tutorial is going to cover how to create a Java REST client using Apache HttpClient.
1. Preparation
Let’s assume that we have a RESTful web service for managing a library with several API as below:
1.1. Get all books
1 |
GET http://localhost:8080/v1/books |
1.2. Create a new book
1 |
POST http://localhost:8080/v1/books |
Example:
1 2 3 4 |
{ "name": "Java How To Program", "author": "Paul Deitel" } |
Responses: application/json
Example:
1 2 3 4 5 |
{ "id": 5 "name": "Java How To Program", "author": "Paul Deitel" } |
STATUS 201 if the book is created successfully.
1.3. Update a book
1 |
PUT http://localhost:8080/v1/books/{id} |
Example:
1 2 3 4 5 |
{ "id": 1, "name": "Java How To Program 2nd", "author": "Paul Deitel" } |
Responses: application/json
STATUS 200 if the book is updated successfully.
STATUS 400 if there is no book with given id
1.4. Delete a book
1 |
DELETE http://localhost:8080/v1/books/{id} |
STATUS 204 if the book is deleted successfully.
STATUS 400 if there is no book with given id or cannot delete the book.
1.5. Source code
The demo source code can be found on the Github.
We use httpasyncclient for communicating with the RESTful API and use jackson-databind to convert Java objects to JSON and vice versa.
1 2 3 4 5 6 7 8 9 10 |
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpasyncclient</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.5</version> </dependency> |
2. Create Java REST Client Using Apache HttpClient
Now, let’s get to some examples of creating Java REST client using Apache HttpClient. We’re going to query, create, update and delete a resource from the above RESTful web service.
2.1. Using Apache HttpClient to Make a GET request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class BookRepositoryImplApacheHttpClient { private static final String URI_BOOK = "http://localhost:8080/v1/books"; public Book[] getAllBooks() throws Exception { Book[] books = null; // Create an asyn HttpClient CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault(); try { httpclient.start(); HttpGet request = new HttpGet(URI_BOOK); Future<HttpResponse> future = httpclient.execute(request, null); // Wait and retrieve the result HttpResponse response = future.get(); System.out.println("Response code:" + response.getStatusLine().getStatusCode()); // Determine whether the request was successfully or not if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity httpEntity = response.getEntity(); // Create a Jackson ObjectMapper to convert the JSON response to Java objects ObjectMapper mapper = new ObjectMapper(); // Read the inputstream and convert to an array of Book books = mapper.readValue(httpEntity.getContent(), Book[].class); } } finally { HttpAsyncClientUtils.closeQuietly(httpclient); } return books; } } |
We update the main method to test the method as below:
1 2 3 4 5 6 |
public static void main(String[] args) throws Exception { BookRepositoryImplApacheHttpClient repository = new BookRepositoryImplApacheHttpClient(); Book[] books = repository.getAllBooks(); System.out.println(books[0]); } |
The output in my console:
1 2 |
Response code:200 Book [id=2, name=Thinking in Java, author=Bruce Eckel] |
2.2. Using Apache HttpClient to make a POST request
In this example, we will use the 2nd API to create a book.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
public class BookRepositoryImplApacheHttpClient { private static final String URI_BOOK = "http://localhost:8080/v1/books"; public Book createBook(Book book) throws Exception { CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault(); Book createdBook = null; try { httpclient.start(); // Create a post method instance. HttpPost request = new HttpPost(URI_BOOK); request.setHeader("Content-type", "application/json"); // Create new instance of ObjectMapper ObjectMapper mapper = new ObjectMapper(); String jsonBook = mapper.writeValueAsString(book); StringEntity entity = new StringEntity(jsonBook); // Set the entity for the request request.setEntity(entity); Future<HttpResponse> future = httpclient.execute(request, null); // Wait and retrieve the result HttpResponse response = future.get(); System.out.println("Response code:" + response.getStatusLine().getStatusCode()); // Determine whether the request was successfully or not if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) { // Get back the created book createdBook = mapper.readValue(response.getEntity().getContent(), Book.class); } } finally { HttpAsyncClientUtils.closeQuietly(httpclient); } return createdBook; } } |
Because the REST API requires the POST method, we create an instance of the HttpPost class. And to convert the given book into JSON string, we leverage the ObjectMapper. If the StatusCode returned from the server is 201 (SC_CREATED), we convert back the response from JSON string to the book that has just been created. The book should have updated fields from the server.
We update the main method for testing.
1 2 3 4 5 6 7 |
public static void main(String[] args) throws Exception { BookRepositoryImplApacheHttpClient bookRepository = new BookRepositoryImplApacheHttpClient(); Book book = new Book(null, "Effective Java", "Joshua Bloch"); Book createdBook = bookRepository.createBook(book); System.out.println(createdBook); } |
The output of my console:
1 2 |
Response code:201 Book [id=3, name=Effective Java, author=Joshua Bloch] |
2.3. Using Apache HttpClient to make a PUT request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public class BookRepositoryImplApacheHttpClient { private static final String URI_BOOK = "http://localhost:8080/v1/books"; public Book updateBook(Book book) throws Exception { CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault(); Book createdBook = null; try { httpclient.start(); // Create a HttpPut instance. HttpPut request = new HttpPut(URI_BOOK + "/" + book.getId()); request.setHeader("Content-type", "application/json"); // Create new instance of ObjectMapper ObjectMapper mapper = new ObjectMapper(); String jsonBook = mapper.writeValueAsString(book); StringEntity entity = new StringEntity(jsonBook); // Set the entity for the request request.setEntity(entity); Future<HttpResponse> future = httpclient.execute(request, null); // Wait and retrieve the result HttpResponse response = future.get(); System.out.println("Response code:" + response.getStatusLine().getStatusCode()); // Determine whether the request was successfully or not if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // Get back the updated book createdBook = mapper.readValue(response.getEntity().getContent(), Book.class); } } finally { HttpAsyncClientUtils.closeQuietly(httpclient); } return createdBook; } } |
According to the API, to update a given Book, we have to issue an HTTP request with the HTTP PUT method to the RESTful API; therefore, we create an instance of HttpPut with the URI. Then we use the Jackson ObjectMapper to convert the object “book” into JSON format because that was required by the API.
And in similar to above example, if the StatusCode returned from the server is 20 (SC_OK), we convert back the response from JSON string to a Book object.
Let’s the main method after updating:
1 2 3 4 5 6 7 8 9 10 11 12 |
public static void main(String[] args) throws Exception { BookRepositoryImplApacheHttpClient bookRepository = new BookRepositoryImplApacheHttpClient(); // Getting the first book from the RESTful service Book book = bookRepository.getAllBooks()[0]; System.out.println(book); // Change the name book.setName(book.getName() + " 3rd"); // Then update the book book = bookRepository.updateBook(book); System.out.println(book); } |
And output of the console after running it:
1 2 3 |
Book [id=2, name=Thinking in Java, author=Bruce Eckel] Response code:200 Book [id=2, name=Thinking in Java 3rd, author=Bruce Eckel] |
2.4. Using Apache HttpClient to make a DELETE request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class BookRepositoryImplApacheHttpClient { private static final String URI_BOOK = "http://localhost:8080/v1/books"; public void deleteBook(Long id) throws Exception { CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault(); try { httpclient.start(); // Create a delete method instance. HttpDelete request = new HttpDelete(URI_BOOK + "/" + id); Future<HttpResponse> future = httpclient.execute(request, null); // Wait and retrieve the result HttpResponse response = future.get(); System.out.println("Response code:" + response.getStatusLine().getStatusCode()); // Determine whether the request was successfully or not if (response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) { throw new RuntimeException("Failed to delete the book with id:" + id); } } finally { HttpAsyncClientUtils.closeQuietly(httpclient); } } } |
To delete a book, we have to issue an HTTP request with DELETE method; so, we create a new instance of the HttpDelete class. We get back the response and check whether the StatusCode is 204 (SC_NO_CONTENT) or not.
We update the main method to test as below:
1 2 3 4 5 6 7 |
public static void main(String[] args) throws Exception { BookRepositoryImplApacheHttpClient bookRepository = new BookRepositoryImplApacheHttpClient(); // Getting the first book from the RESTful service Book book = bookRepository.getAllBooks()[0]; bookRepository.deleteBook(book.getId()); } |
The output of my console is:
1 |
Response code:204 |
4. Conclusion
The tutorial has illustrated us how to implement a Java REST client using Apache HttpClient. Note that we’ve implemented those examples using httpasyncclient module while another module we can use is HttpClient. In near future, I will provide more examples of implementing RESTful client with other libraries, frameworks. Recently, I have had several posts on the same topic. Please refer following links:
Simple Java REST Client Using java.net.URL package(using the built-in package java.net.URL of the JDK)
Java REST Client Using Spring RestTemplate
Java REST Client Using Resteasy Client
Java REST Client Using Jersey Client
Java REST Client Using Resteasy Client Proxy Framework
Java REST Client Using Netflix Feign
Java REST Client Examples Using OkHttp