杰瑞科技汇

httpclient java

Of course! Here is a comprehensive guide to using the Apache HttpClient library in Java, covering everything from basic setup to advanced features.

What is Apache HttpClient?

Apache HttpClient is a robust and feature-rich library for making HTTP requests in Java. While Java has built-in HttpURLConnection, it's often cumbersome and less powerful. HttpClient provides a modern, fluent, and highly configurable API that makes it the de-facto standard for HTTP communication in Java applications.


Setup (Adding the Dependency)

First, you need to add the HttpClient dependency to your project. The most common way is using Maven or Gradle.

Using Maven (pom.xml)

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version> <!-- Check for the latest version -->
</dependency>

Using Gradle (build.gradle)

implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1' // Check for the latest version

Making a Simple GET Request

This is the most common use case. We'll make a GET request to a public API and process the response.

The modern, recommended approach is to use the HttpClient with HttpResponse and EntityUtils.

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.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
public class SimpleGetRequest {
    public static void main(String[] args) {
        // The URL to request
        String url = "https://jsonplaceholder.typicode.com/posts/1";
        // Use try-with-resources to ensure the client and response are closed automatically
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // Create the HTTP GET request
            HttpGet request = new HttpGet(url);
            // Execute the request and get the response
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                // Get the response entity (the actual content)
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    // Convert the response entity to a String
                    String result = EntityUtils.toString(entity);
                    // Print the result
                    System.out.println("Response Body:");
                    System.out.println(result);
                    // You can also get other response information
                    System.out.println("\nResponse Status: " + response.getCode());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Key Points:

  • CloseableHttpClient: The main client object for sending requests. It's recommended to use a single instance and reuse it.
  • try-with-resources: This is crucial. It ensures that CloseableHttpClient and CloseableHttpResponse are properly closed, preventing resource leaks.
  • HttpGet: Represents the HTTP GET request method.
  • response.getEntity(): Returns the response body as an HttpEntity.
  • EntityUtils.toString(entity): A utility to easily read the entity content into a String.

Making a POST Request with a JSON Body

To send data (like creating a new resource), you use a POST request. This involves creating a JSON string and setting it as the request body.

import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.io.entity.EntityUtils;
public class SimplePostRequest {
    public static void main(String[] args) {
        String url = "https://jsonplaceholder.typicode.com/posts";
        String jsonPayload = "{\n  \"title\": \"foo\",\n  \"body\": \"bar\",\n  \"userId\": 1\n}";
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // Create the HTTP POST request
            HttpPost httpPost = new HttpPost(url);
            // Set the JSON payload
            StringEntity entity = new StringEntity(jsonPayload, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // Execute the request
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    String result = EntityUtils.toString(responseEntity);
                    System.out.println("Response Body:");
                    System.out.println(result);
                    System.out.println("\nResponse Status: " + response.getCode());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Key Points:

  • HttpPost: Represents the HTTP POST request method.
  • StringEntity: Used to wrap our JSON string into an HttpEntity.
  • ContentType.APPLICATION_JSON: Tells the server that we are sending JSON data. It sets the Content-Type header to application/json.
  • httpPost.setEntity(entity): Attaches the payload to the request.

Handling Headers

You can easily add custom headers to your requests.

HttpGet request = new Get("https://example.com/api/data");
// Add a custom header
request.addHeader("Accept", "application/json");
request.addHeader("X-Custom-Header", "MyValue");
// You can also set headers instead of adding them
request.setHeader("Authorization", "Bearer my-secret-token");

Setting Timeouts

It's critical to set timeouts to prevent your application from hanging indefinitely.

// Create a custom RequestConfig
RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(5000) // Time to establish the connection (5 seconds)
        .setConnectionRequestTimeout(5000) // Time to get a connection from the pool (5 seconds)
        .setResponseTimeout(10000) // Time to wait for the response (10 seconds)
        .build();
// Create a client with the custom config
try (CloseableHttpClient httpClient = HttpClients.custom()
        .setDefaultRequestConfig(requestConfig)
        .build()) {
    HttpGet request = new Get("https://api.example.com/slow-endpoint");
    // ... execute the request
}

Asynchronous (Non-Blocking) Requests

HttpClient 5 supports non-blocking I/O using the HttpAsyncClient. This is ideal for applications that need high concurrency, like microservices.

import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpResponse;
public class AsyncGetRequest {
    public static void main(String[] args) throws Exception {
        try (CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault()) {
            // Start the client
            httpClient.start();
            // Create the request
            SimpleHttpRequest request = SimpleRequestBuilder.get("https://jsonplaceholder.typicode.com/posts/1").build();
            // Execute the request asynchronously
            System.out.println("Executing async request...");
            httpClient.execute(request, new FutureCallback<SimpleHttpResponse>() {
                @Override
                public void completed(SimpleHttpResponse response) {
                    System.out.println("Request completed!");
                    System.out.println("Response Status: " + response.getCode());
                    System.out.println("Response Body: " + response.getBodyText());
                }
                @Override
                public void failed(Exception ex) {
                    System.err.println("Request failed: " + ex.getMessage());
                }
                @Override
                public void cancelled() {
                    System.out.println("Request was cancelled.");
                }
            });
            // Wait for the callback to be invoked (in a real app, you wouldn't do this)
            System.out.println("Waiting for response...");
            Thread.sleep(5000); 
        }
    }
}

Key Points:

  • CloseableHttpAsyncClient: The client for async operations.
  • httpClient.start(): Must be called before executing requests.
  • FutureCallback: A callback interface that gets notified when the request completes, fails, or is cancelled.
  • The main thread is not blocked, allowing it to do other work.

Best Practices

  1. Reuse HttpClient Instances: Creating a new HttpClient for every request is very inefficient. Reuse a single instance for the lifetime of your application.
  2. Always Use try-with-resources: Ensure that CloseableHttpClient and CloseableHttpResponse are closed to release system resources.
  3. Consume and Release Response Entities: Always call EntityUtils.consume(entity) or EntityUtils.toString(entity) on the response entity to ensure the underlying connection is released back to the connection manager. The try-with-resources block on CloseableHttpResponse helps with this.
  4. Set Timeouts: Always configure connection, request, and response timeouts to avoid hanging your application.
  5. Handle Exceptions: Network requests can fail for many reasons (DNS, connection refused, timeout, etc.). Wrap your calls in try-catch blocks to handle IOException and other relevant exceptions gracefully.

HttpClient 5 vs. Older Versions (4.x)

If you find tutorials using HttpClient 4.x, note the key differences:

  • Package Names: org.apache.http.client -> org.apache.hc.client5.http
  • Classes: HttpClient -> CloseableHttpClient, HttpGet -> ClassicHttpRequest, HttpResponse -> ClassicHttpResponse
  • Response Handling: response.getEntity().getContent() is replaced by EntityUtils.toString() or EntityUtils.toByteArray().
  • Async: The async client is now a separate, more mature implementation.

HttpClient 5 is the current major version and is recommended for all new projects.

分享:
扫描分享到社交APP
上一篇
下一篇