Explain Codes LogoExplain Codes Logo

Deprecated Java HttpClient - How hard can it be?

java
httpclient
exception-handling
connection-pooling
Anton ShumikhinbyAnton Shumikhin·Aug 13, 2024
TLDR

For vastly improved functionality, switch to the latest version of Apache HttpClient 5.x which is instantiated via HttpClientBuilder.create().build(). Below is an example:

import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.client5.http.fluent.Request; // Execute GET and retrieve response content, in one line. Because who needs multiple lines anyway? String result = EntityUtils.toString(Request.get("http://example.com").execute().returnContent());

This single liner demonstrates a GET request, which then retrieves the response content as a String. It's the beauty of HttpClient 5.x in its simplest form.

Upgraded resource handling: Try-with-resources

It's preferable to handle resources using the try-with-resources syntax, available in Java 7 and onwards. It ensures swelling your resource pool like a leaky water balloon is avoided. Conveniently, CloseableHttpClient implements AutoCloseable, making it an excellent candidate:

import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; try (CloseableHttpClient client = HttpClients.createDefault()) { HttpGet httpGet = new HttpGet("http://example.com"); // Execute and handle response like a pro } // Client gets auto-closed here, so you don't have to smother it with a pillow

Exception handling: Arm your code

As a variant of Murphy's Law states, "If something can go wrong, it will." When managing HttpClient operations, it's crucial to facilitate IOException handling. Wrap your rallying network cry in a try-catch clause to manage potential IO fiascoes gracefully:

try { // HttpClient operations go here } catch (IOException e) { e.printStackTrace(); // Surely you can handle an exception more creatively than this? }

HttpClientBuilder: Your gateway to configuration

Have you ever felt the need to inject specific settings into your HttpClient? With HttpClientBuilder, setting timeouts and connection specifics can be as easy as changing a lightbulb:

import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(TIMEOUT_MS) .setConnectionRequestTimeout(TIMEOUT_MS) .setSocketTimeout(TIMEOUT_MS) .build(); CloseableHttpClient client = HttpClients.custom() .setDefaultRequestConfig(requestConfig) .build();

JSON data processing: Simplified

Want to process JSON data gracefully? Envelop your InputStream in a BufferedReader and then employ a StringBuilder to amass the JSON response like an acorn-hoarding squirrel:

import java.io.BufferedReader; import java.io.InputStreamReader; try (BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()))) { StringBuilder json = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { json.append(line); } // Now `json.toString()` is your new JSON superhero }

Connection pooling: Be the Pool Party King

During periods of intense request traffic, managing your connection pool is as important as wearing sunscreen on a beach. With PoolingHttpClientConnectionManager, you can customize and keep track of your connections, and ensure no one is peeing in the pool (figuratively):

import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(100); // Total connections cm.setDefaultMaxPerRoute(10); // Connections per route. Because sharing is caring! CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(cm) .build();

Maven dependency: Stay on the bleeding edge

Like sipping the morning coffee, keeping your Maven dependencies updated is essential. Ensure that you're using the latest stable version of HttpClient in your pom.xml, because nobody enjoys exploiting security vulnerabilities at a later date:

<dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>YOUR_LATEST_STABLE_VERSION_HERE</version> </dependency>

Additional guidance: Broaden your horizons

Dive into the Apache HttpClient examples and JavaDoc to gain a deeper understanding and greater control over your HTTP transactions. You might discover gold nuggets of information that could change the way you handle HttpClient usage.

Extra tip: Unconventional JSON acquisition

Apart from HttpClient, consider using URLConnection if it gels with your style. It downloads JSON data right off a URL, like stealing candy from a baby (not that you should ever do that):

import java.io.InputStream; import java.net.URL; import java.net.URLConnection; URL url = new URL("http://example.com/data.json"); URLConnection connection = url.openConnection(); try (InputStream stream = connection.getInputStream()) { // Handle stream here. Remember: InputStream, not beer stream! }