当前位置: 首页 > news >正文

详细分析HttpClient的基本知识(附Demo实战思路)

目录

  • 前言
  • 1. Java8 Demo
  • 2. Java8 实战
  • 3. Java11 Demo

前言

🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF

1. Java8 Demo

下述主体主要针对Java8的版本,后续会有一个特定的Java11版本

推荐使用 Apache HttpClient 4.x,这是在 Java 8 中使用最广泛、最稳定的 HTTP 客户端工具

Apache HttpClient 是 Apache 出品的 HTTP 客户端库,功能强大,适用于:

  • 发起 HTTP 请求(GET、POST、PUT、DELETE 等)

  • 携带请求头、请求参数

  • 设置超时、重定向等策略

  • 读取响应状态码、响应体、响应头等

导入相关的依赖包:

<!-- Apache HttpClient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version> <!-- 推荐稳定版本 -->
</dependency>

相关的核心类如下:

类名说明
CloseableHttpClient客户端对象,用于发送请求
HttpGet / HttpPost表示 HTTP 请求(GET/POST)
HttpResponse响应对象
HttpEntity请求体或响应体封装
EntityUtils帮助读取响应体为字符串等形式

以下Demo主要用于测试使用,便于理解其用法说明:

Get请求:

import org.apache.http.HttpResponse;
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;

public class ApacheHttpGetDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建 HttpClient 实例
        CloseableHttpClient client = HttpClients.createDefault();

        // 2. 创建 HttpGet 请求对象,并设置 URL
        HttpGet get = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");

        // 3. 执行请求,获取响应
        HttpResponse response = client.execute(get);

        // 4. 获取状态码
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("状态码: " + statusCode);

        // 5. 获取响应体内容
        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
        System.out.println("响应内容: \n" + responseBody);

        // 6. 关闭客户端连接
        client.close();
    }
}

Post请求:

import org.apache.http.HttpResponse;
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;

public class ApacheHttpPostDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建 HttpClient 实例
        CloseableHttpClient client = HttpClients.createDefault();

        // 2. 创建 HttpPost 请求对象
        HttpPost post = new HttpPost("https://jsonplaceholder.typicode.com/posts");

        // 3. 构造 JSON 请求体(Java 8 用字符串拼接)
        String json = "{"
                + "\"title\": \"foo\","
                + "\"body\": \"bar\","
                + "\"userId\": 1"
                + "}";

        // 4. 设置请求头和请求体
        post.setHeader("Content-Type", "application/json");
        post.setEntity(new StringEntity(json, "UTF-8"));

        // 5. 发送 POST 请求
        HttpResponse response = client.execute(post);

        // 6. 读取响应状态码和响应体
        int statusCode = response.getStatusLine().getStatusCode();
        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");

        // 7. 打印结果
        System.out.println("状态码: " + statusCode);
        System.out.println("响应内容:\n" + responseBody);

        // 8. 关闭客户端
        client.close();
    }
}

上述常用方法总结
✅ 创建客户端:CloseableHttpClient client = HttpClients.createDefault();

✅ GET 请求:HttpGet get = new HttpGet("http://example.com/api");

✅ POST 请求 + JSON

HttpPost post = new HttpPost("http://example.com/api");
post.setHeader("Content-Type", "application/json");
post.setEntity(new StringEntity(jsonData, "UTF-8"));

✅ 发送请求 + 获取响应

HttpResponse response = client.execute(get或post);
int statusCode = response.getStatusLine().getStatusCode();
String body = EntityUtils.toString(response.getEntity(), "UTF-8");

✅ 设置请求头

post.setHeader("Authorization", "Bearer your-token");
post.setHeader("Accept", "application/json");

2. Java8 实战

对接的API接口是一张照片,之后将识别结果返回,比对是否两者一致!

实战中的Demo如下,实战中的Demo主要以思路讲解的方式:

// 某个接口中有所调用API传输文件,得到AI识别结果:
String result = uploadImageAndRecognize(downloadedFile);

// 具体调用的方法参数:
private String uploadImageAndRecognize(File imageFile) throws IOException {
    String url = "http://xxxx/recognize";

    // 创建HttpClient
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // 创建 POST 请求
    HttpPost uploadFile = new HttpPost(url);
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody(
            "image",
            new FileInputStream(imageFile),
            ContentType.APPLICATION_OCTET_STREAM,
            imageFile.getName()
    );
    HttpEntity multipart = builder.build();
    uploadFile.setEntity(multipart);

    // 执行请求
    CloseableHttpResponse response = httpClient.execute(uploadFile);
    HttpEntity responseEntity = response.getEntity();

    if (responseEntity != null) {
        String jsonString = EntityUtils.toString(responseEntity);
        // 解析 JSON,提取结果
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(jsonString);
        JsonNode resultsNode = rootNode.path("results");

        if (resultsNode.isArray() && resultsNode.size() > 0) {
            return resultsNode.get(0).asText(); // 返回第一个结果
        }
    }

    return null; // 如果解析失败或无结果
}

方法结构核心知识点:

  1. CloseableHttpClient httpClient = HttpClients.createDefault();
    创建一个 HttpClient 客户端实例
    用于执行 HTTP 请求,属于同步阻塞操作

  2. HttpPost uploadFile = new HttpPost(url);
    创建一个 POST 请求对象,URL 是目标服务端 API 接口

  3. MultipartEntityBuilder
    用于构建带文件上传的 multipart/form-data 请求体
    addBinaryBody() 表示添加文件字段,支持设置内容类型和文件名

  4. httpClient.execute(uploadFile)
    执行请求,阻塞线程直到响应返回
    返回的是 CloseableHttpResponse 对象

  5. EntityUtils.toString(responseEntity)
    将响应实体转为字符串格式(JSON文本)。

  6. ObjectMapper 解析 JSON

ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonString);
JsonNode resultsNode = rootNode.path("results");

使用 Jackson 库解析 JSON
path() 用于安全地访问节点,避免 null 指针

  1. 返回识别结果
if (resultsNode.isArray() && resultsNode.size() > 0) {
    return resultsNode.get(0).asText();
}

后续还可进一步优化:

在这里插入图片描述

为什么用 CompletableFuture?

异步处理耗时任务(如 HTTP 请求)时,主线程无需等待
非阻塞性能更好,适合高并发场景
支持链式调用、异常处理、并发组合等高级特性

整体改进如下:

✅ 1. 异步化请求(使用 CompletableFuture)
通过异步处理,你可以避免等待 HTTP 请求的过程,减少主线程阻塞,提升性能。使用 CompletableFuture 可以让你并行处理多个请求。

import java.util.concurrent.CompletableFuture;

private CompletableFuture<String> uploadImageAndRecognizeAsync(File imageFile) {
    return CompletableFuture.supplyAsync(() -> {
        try {
            return uploadImageAndRecognize(imageFile);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    });
}

在调用处,可以异步执行,并在适当的时候等待结果

String key = "xxxxx";
Boolean newStatus = redisTemplate.opsForValue().get(key) == null;
if (newStatus) {
    File downloadedFile = null;
    try {
        downloadedFile = downloadFileFromUrl(createReqVO.getImgCntrF());

        // 异步调用AI校验接口
        CompletableFuture<String> futureResult = uploadImageAndRecognizeAsync(downloadedFile);
        
        // 等待结果并处理
        String result = futureResult.get();  // 可以加上超时处理
        System.out.println("识别结果: " + result);
        
        // 进一步处理结果...
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

✅ 2. 封装 HTTP 请求
为了避免重复代码,你可以把 HTTP 请求的部分封装成一个独立的工具类。这样可以提高代码的可维护性和可重用性。

HttpClientUtils 工具类:

public class HttpClientUtils {

    /**
     * 发送POST请求上传图片并获取识别结果
     * @param url 请求的URL
     * @param imageFile 需要上传的图片文件
     * @return 识别结果
     * @throws IOException
     */
    public static String postFile(String url, File imageFile) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost uploadFile = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody(
                    "image",
                    new FileInputStream(imageFile),
                    ContentType.APPLICATION_OCTET_STREAM,
                    imageFile.getName()
            );
            HttpEntity multipart = builder.build();
            uploadFile.setEntity(multipart);

            try (CloseableHttpResponse response = httpClient.execute(uploadFile)) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    String jsonString = EntityUtils.toString(responseEntity);
                    ObjectMapper objectMapper = new ObjectMapper();
                    JsonNode rootNode = objectMapper.readTree(jsonString);
                    JsonNode resultsNode = rootNode.path("results");

                    if (resultsNode.isArray() && resultsNode.size() > 0) {
                        return resultsNode.get(0).asText();  // 返回第一个识别结果
                    }
                }
            }
        }
        return null; // 如果没有获取到识别结果
    }
}

然后,调用时直接使用工具类:

String key = "xxxx";
Boolean newStatus = redisTemplate.opsForValue().get(key) == null;
if (newStatus) {
    File downloadedFile = null;
    try {
        downloadedFile = downloadFileFromUrl(createReqVO.getImgCntrF());

        // 调用工具类进行图片上传与识别
        String result = HttpClientUtils.postFile("http://10.197.2.16:5000/api/recognize", downloadedFile);
        System.out.println("识别结果: " + result);
        
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

✅ 3. 异常处理与重试机制
考虑到网络请求的可能失败,可以加入重试机制。比如在请求失败时可以重试几次,使用 RetryTemplate 或 Spring Retry 可以实现。

下面是一个简单的重试实现:

import org.springframework.retry.support.RetryTemplate;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;

public class RetryHttpClientUtils {

    private static RetryTemplate createRetryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();

        // 设置重试策略:最多重试3次
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3);
        retryTemplate.setRetryPolicy(retryPolicy);

        // 设置重试的退避策略:指数退避
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(1000); // 初始间隔时间:1秒
        backOffPolicy.setMultiplier(2); // 每次间隔时间倍增
        retryTemplate.setBackOffPolicy(backOffPolicy);

        return retryTemplate;
    }

    public static String postFileWithRetry(String url, File imageFile) throws IOException {
        RetryTemplate retryTemplate = createRetryTemplate();
        return retryTemplate.execute(context -> HttpClientUtils.postFile(url, imageFile));
    }
}

3. Java11 Demo

后续发现一个野生的Java11版本

Java 11 之后,HttpClient 成为了标准库的一部分(位于 java.net.http 包中)

核心类:

类名说明
HttpClientHTTP 客户端,用于发送请求、接收响应
HttpRequest表示一个 HTTP 请求(如 GET/POST)
HttpResponse表示响应结果,包括状态码、响应体等
HttpRequest.BodyPublishers用于构造请求体
HttpResponse.BodyHandlers用于处理响应体

基本的逻辑步骤如下:

  1. 创建 HttpClient 客户端对象

  2. 构造 HttpRequest 请求对象

  3. 发送请求并获取 HttpResponse 响应对象

Get请求:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClientGetDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建 HttpClient 实例
        HttpClient client = HttpClient.newHttpClient();

        // 2. 构造 GET 请求(指定 URI)
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("https://jsonplaceholder.typicode.com/posts/1"))
                .GET() // 默认就是 GET
                .build();

        // 3. 发送请求并获取响应
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // 4. 打印状态码和响应体
        System.out.println("状态码: " + response.statusCode());
        System.out.println("响应内容: \n" + response.body());
    }
}

Post请求:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;

public class HttpClientPostDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建 HttpClient 实例
        HttpClient client = HttpClient.newHttpClient();

        // 2. 构造 POST 请求,发送 JSON 数据
        String json = """
                {
                    "title": "foo",
                    "body": "bar",
                    "userId": 1
                }
                """;

        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("https://jsonplaceholder.typicode.com/posts"))
                .header("Content-Type", "application/json") // 设置请求头
                .POST(BodyPublishers.ofString(json)) // 设置请求体
                .build();

        // 3. 发送请求并接收响应
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // 4. 打印状态码和响应内容
        System.out.println("状态码: " + response.statusCode());
        System.out.println("响应内容: \n" + response.body());
    }
}

常用方法分析

HttpClient 创建

HttpClient client = HttpClient.newHttpClient(); // 默认配置
HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_2)
        .followRedirects(HttpClient.Redirect.NORMAL)
        .build();

HttpRequest 构建方法

// GET 请求
HttpRequest.newBuilder().uri(new URI("...")).GET().build();

// POST 请求
HttpRequest.newBuilder().uri(new URI("..."))
        .POST(BodyPublishers.ofString("请求体"))
        .build();

// 设置请求头
.header("Content-Type", "application/json")

HttpResponse 处理方式

HttpResponse.BodyHandlers.ofString(); // 将响应体转为字符串
HttpResponse.BodyHandlers.ofByteArray(); // 转为字节数组
HttpResponse.BodyHandlers.ofFile(Path.of("output.txt")); // 写入文件

相关文章:

  • SEV内存加密位linux内核设置过程
  • C++锁: 读锁,递归锁,超时锁
  • 2025系统分析师---软件工程:深度剖析常见软件开发方法
  • Nature Machine Intelligence 嵌入式大语言模型使机器人能够在不可预测的环境中完成复杂的任务
  • WordPress WooCommerce 本地文件包含漏洞(CVE-2025-1661)
  • 网络编程基础知识——从基础到实操
  • 常见框架漏洞(一)----Thinkphp(TP)
  • Android之卡片式滑动
  • 零基础上手Python数据分析 (9):DataFrame 数据读取与写入 - 让数据自由穿梭
  • 基于Java的班级事务管理系统(源码+lw+部署文档+讲解),源码可白嫖!
  • HarmonyOS-ArkUI Grip组件
  • Charles汉化步骤 charles中文版怎么用
  • 凝视型高光谱相机:钻石光谱分析研究与应用
  • PoE交换机如何助力智慧城市基础设施建设?
  • C# 如何检查给定的四个点是否形成一个正方形(How to check if given four points form a square)
  • docker ssh远程连接
  • uni app跨端开发遇到的问题
  • Linux搭建本地时间服务器及时间同步
  • mysql中show命令的使用
  • react-activation 实现页面保活记录
  • 传奇做网站空间/郑州网络推广服务
  • 网站建设排行/百度搜索资源平台token
  • 网站开发一般需要多久/常见的搜索引擎有哪些
  • 建设银行在上海的招聘网站/百度关键词首页排名服务
  • wordpress评论通知代码6/seo sem推广
  • 电子网站建设ppt模板/赛雷猴是什么意思