Apache HttpClient simplifies the interactions with RESTful APIs by supporting various HTTP methods, headers, and request configurations. This article will explore how to consume REST APIs using Apache HttpClient5 with examples.
1. Setup
Before diving into implementation, we need to import the latest version of Apache HttpClient.
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.4.1</version>
</dependency>
Next, we will need to create a basic HttpClient instance. We are using CloseableHttpClient which is the primary class in the HttpClient library for executing HTTP requests. This class implements Closeable
interface and ensures that connections are properly closed after use.
The CloseableHttpClient also supports the configuration of timeouts, connection pooling, and authentication.
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.config.RequestConfig;
public class CustomHttpClientConfig {
public static CloseableHttpClient createCustomHttpClient() {
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(5000)
.setResponseTimeout(5000)
.build();
return HttpClients.custom()
.setDefaultRequestConfig(config)
.build();
}
}
2. REST APIs
The HTTP GET and POST REST APIs I will access are as defined.
@POST
@Path("/users")
public User addUser(User user) {
// Implementation to add a user
}
@GET
@Path("/users")
public List<User> all() {
// Implementation to retrieve all users
}
@GET
@Path("/users/{id}")
public User getById(@PathParam("id") Integer id) {
// Implementation to retrieve a user by ID
}
3. POST API Example
Java program for creating a new User in the system by consuming the POST /users rest api.
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpStatus;
import com.fasterxml.jackson.databind.ObjectMapper;
// Inside some method
CloseableHttpClient httpClient = HttpClientConfig.createHttpClient();
HttpPost postRequest = new HttpPost("http://localhost:8080/users");
User newUser = new User("John", "Doe", "[email protected]");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(newUser);
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
postRequest.setEntity(entity);
try (CloseableHttpResponse response = httpClient.execute(postRequest)) {
int statusCode = response.getCode();
if (statusCode == HttpStatus.SC_CREATED) {
String responseBody = EntityUtils.toString(response.getEntity());
User createdUser = mapper.readValue(responseBody, User.class);
System.out.println("User created: " + createdUser);
} else {
System.err.println("Failed to create user. HTTP Status: " + statusCode);
}
} catch (Exception e) {
e.printStackTrace();
}
4. GET API Example
The following example fetches all the users in a list by invoking the GET /users API.
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.HttpStatus;
import java.util.List;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
CloseableHttpClient httpClient = HttpClientConfig.createHttpClient();
HttpGet getRequest = new HttpGet("http://localhost:8080/users");
try (CloseableHttpResponse response = httpClient.execute(getRequest)) {
int statusCode = response.getCode();
if (statusCode == HttpStatus.SC_OK) {
String responseBody = EntityUtils.toString(response.getEntity());
ObjectMapper mapper = new ObjectMapper();
List<User> users = mapper.readValue(responseBody, new TypeReference<List<User>>() {});
users.forEach(System.out::println);
} else {
System.err.println("Failed to fetch users. HTTP Status: " + statusCode);
}
} catch (Exception e) {
e.printStackTrace();
}
Similarly, we can fetch the details of a user by invoking GET /users/{id} API.
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.HttpStatus;
import com.fasterxml.jackson.databind.ObjectMapper;
CloseableHttpClient httpClient = HttpClientConfig.createHttpClient();
int userId = 1;
HttpGet getRequest = new HttpGet("http://localhost:8080/users/" + userId);
try (CloseableHttpResponse response = httpClient.execute(getRequest)) {
int statusCode = response.getCode();
if (statusCode == HttpStatus.SC_OK) {
String responseBody = EntityUtils.toString(response.getEntity());
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(responseBody, User.class);
System.out.println("User retrieved: " + user);
} else {
System.err.println("Failed to fetch user. HTTP Status: " + statusCode);
}
} catch (Exception e) {
e.printStackTrace();
}
5. Sending Headers and Authentication Details
Here is how to send custom headers and basic authentication:
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
//Add auth details in the httpclient instance
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("localhost", 8080),
new UsernamePasswordCredentials("admin", "password".toCharArray()));
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
HttpGet getRequest = new HttpGet("http://localhost:8080/protected-resource");
//Adding headers
getRequest.addHeader("Custom-Header", "CustomValue");
try (CloseableHttpResponse response = httpClient.execute(getRequest)) {
int statusCode = response.getCode();
if (statusCode == HttpStatus.SC_OK) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response: " + responseBody);
} else {
System.err.println("Failed to access resource. HTTP Status: " + statusCode);
}
} catch (Exception e) {
e.printStackTrace();
}
6. Sending and Receiving Cookies
The BasicCookieStore class can used to manage cookies automatically during HTTP communication. It implements the CookieStore interface and provides a thread-safe way to store, retrieve, and manage cookies.
- For incoming requests, the HttpClient detects the cookies and stores them in the BasicCookieStore.
- For outgoing requests, the HttpClient checks the cookies in the BasicCookieStore to see if any match the target domain, path, and other properties. If a match is found, those cookies are added to the request (Cookie header).
- We can also manually inspect, add, or remove cookies in the BasicCookieStore.
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.cookie.BasicCookieStore;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.core5.http.cookie.Cookie;
import org.apache.hc.core5.http.io.entity.EntityUtils;
BasicCookieStore cookieStore = new BasicCookieStore();
// Create an HttpClient with the cookie store
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.build();
// Send a GET request
HttpGet getRequest = new HttpGet("http://localhost:8080/users");
try (var response = httpClient.execute(getRequest)) {
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response: " + responseBody);
// Retrieve cookies stored in the CookieStore
List<Cookie> cookies = cookieStore.getCookies();
for (Cookie cookie : cookies) {
System.out.println("Cookie: " + cookie.getName() + " = " + cookie.getValue());
}
} catch (Exception e) {
e.printStackTrace();
}
Drop me your comments on httpclient example of http post request and get request.
Happy Learning !!
Comments