侧边栏壁纸
博主头像
拾荒的小海螺博主等级

只有想不到的,没有做不到的

  • 累计撰写 194 篇文章
  • 累计创建 19 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

JAVA:CloseableHttpClient 进行 HTTP 请求的技术指南

拾荒的小海螺
2024-10-31 / 0 评论 / 0 点赞 / 14 阅读 / 10126 字

1、简述

CloseableHttpClient 是 Apache HttpComponents 提供的一个强大 HTTP 客户端库。它允许 Java 程序与 HTTP/HTTPS 服务交互,可以发送 GET、POST 等各种请求类型,并处理响应。该库广泛用于 REST API 调用、文件上传和下载等场景。

1730908298979.jpg

2、特性

CloseableHttpClient 是 HttpClient 的一个实现类,它可以进行各种 HTTP 请求,并且在使用完毕时支持关闭以释放资源。与其搭配的 HttpResponse 提供了对 HTTP 响应的解析。

主要特性包括:

  • 支持同步和异步请求
  • 支持连接池和重试机制
  • 支持多种请求方法:GET、POST、PUT、DELETE 等
  • 支持表单数据、JSON 数据和文件上传等多种数据格式

3、基础用法

3.1 发送 GET 请求

GET 请求用于从服务器获取资源数据,示例如下:

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class HttpClientExample {
    public static void main(String[] args) {
        // 创建HttpClient实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            // 创建GET请求
            HttpGet request = new HttpGet("http://httpbin.org/get");

            // 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(request)) {

                // 获取响应体
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    // 将响应体转为字符串
                    String result = EntityUtils.toString(entity);
                    System.out.println(result);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.2 发送 POST 请求

POST 请求用于向服务器提交数据,例如表单数据或 JSON 数据:


import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class HttpClientExample {
    public static void main(String[] args) {
        // 创建HttpClient实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            // 创建GET请求
            HttpGet request = new HttpGet("http://httpbin.org/get");

            // 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(request)) {

                // 获取响应体
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    // 将响应体转为字符串
                    String result = EntityUtils.toString(entity);
                    System.out.println(result);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.3 表单数据和文件上传

在实际开发中,通常会遇到需要上传文件的场景。例如,用户通过网页上传文件到服务器,这时就需要使用 MultipartEntityBuilder 来构建多部分表单(form-data)。

上传文件和表单参数 通过 MultipartEntityBuilder 可以轻松实现文件上传和传递其他表单字段:

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.util.Map;

public class HttpClientFileUploadWithParams {

    public static void main(String[] args) {
        // 创建HttpClient实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            // 创建POST请求
            HttpPost postRequest = new HttpPost("http://httpbin.org/post");

            // 模拟表单参数 (key-value 对)
            Map<String, String> formParams = Map.of(
                "username", "john_doe",
                "password", "secret_password"
            );

            // 构建MultipartEntity,添加文件参数和普通表单参数
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody(
                "file", new File("path/to/your/file.txt"),
                ContentType.APPLICATION_OCTET_STREAM, "file.txt"
            );

            // 添加表单参数
            for (Map.Entry<String, String> entry : formParams.entrySet()) {
                builder.addTextBody(entry.getKey(), entry.getValue(), ContentType.TEXT_PLAIN);
            }

            // 设置请求体
            HttpEntity multipart = builder.build();
            postRequest.setEntity(multipart);

            // 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(postRequest)) {
                // 获取响应体
                String result = EntityUtils.toString(response.getEntity());
                System.out.println(result);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.4 使用 Map 传递 JSON 数据

如果需要发送 POST 请求并将数据以 JSON 格式发送,可以使用 Map 构建数据并将其序列化为 JSON 格式:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class HttpClientMapJsonExample {

    public static void main(String[] args) throws IOException {
        // 创建HttpClient实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            // 创建POST请求
            HttpPost postRequest = new HttpPost("http://httpbin.org/post");

            // 模拟参数 (key-value 对)
            Map<String, Object> jsonParams = new HashMap<>();
            jsonParams.put("username", "john_doe");
            jsonParams.put("age", 30);
            jsonParams.put("active", true);

            // 将Map转换为JSON字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(jsonParams);

            // 设置请求体 (JSON格式)
            StringEntity entity = new StringEntity(json);
            postRequest.setEntity(entity);
            postRequest.setHeader("Content-Type", "application/json");

            // 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(postRequest)) {
                // 获取响应体
                String result = EntityUtils.toString(response.getEntity());
                System.out.println(result);
            }
        }
    }
}

4、错误处理和性能优化

4.1错误处理

在使用 CloseableHttpClient 时,建议对 HTTP 请求的响应状态码进行检查,确保服务器返回了预期的结果:

int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
    // 成功处理逻辑
} else {
    System.err.println("请求失败,状态码:" + statusCode);
}

4.2 连接池和超时设置

为了提高性能,可以使用连接池管理多个 HTTP 连接。此外,设置合理的超时时间对于处理网络延迟也是必要的:

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;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.util.Timeout;

public class HttpClientPoolExample {

    public static CloseableHttpClient createHttpClientWithPool() {
        // 创建连接池管理器,并设置最大连接数和每个路由的最大连接数
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(100); // 最大连接数
        connectionManager.setDefaultMaxPerRoute(20); // 每个路由的最大连接数

        // 配置请求的超时时间
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(Timeout.ofSeconds(10))        // 连接超时时间
                .setConnectionRequestTimeout(Timeout.ofSeconds(5)) // 从连接池获取连接的超时时间
                .setResponseTimeout(Timeout.ofSeconds(15))        // 请求超时时间
                .build();

        // 创建带有连接池和请求配置的 HttpClient
        return HttpClients.custom()
                .setConnectionManager(connectionManager) // 设置连接池管理器
                .setDefaultRequestConfig(requestConfig)  // 设置请求配置
                .build();
    }
}

5、总结

通过使用 CloseableHttpClient,可以方便地在 Java 中实现各种 HTTP 请求,包括 GET、POST、文件上传等。在实际开发中,我们可以根据具体业务场景灵活调整请求配置,例如设置超时、使用连接池管理多线程请求等。

这种 HTTP 客户端非常适合 REST API 调用、文件处理等常见应用场景。

0

评论区