java.net.http 包详解

java.net.http 包是 Java 11 引入的 HTTP 客户端 API,提供了现代、灵活且功能强大的 HTTP 客户端功能,替代了传统的 HttpURLConnection


核心类

1. HttpClient

HTTP 客户端的主要入口点,用于发送请求和接收响应。

主要特性:

  • 支持 HTTP/1.1 和 HTTP/2

  • 同步和异步请求

  • WebSocket 支持

  • 连接池管理

  • 重定向处理

  • 认证支持

创建 HttpClient 示例:

java 复制代码
HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)  // 使用HTTP/2
    .followRedirects(HttpClient.Redirect.NORMAL)  // 跟随重定向
    .connectTimeout(Duration.ofSeconds(20))  // 连接超时
    .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))  // 代理
    .authenticator(Authenticator.getDefault())  // 认证
    .build();

2. HttpRequest

表示要发送的 HTTP 请求。

构建请求示例:

java 复制代码
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com/api"))
    .header("Content-Type", "application/json")
    .timeout(Duration.ofMinutes(2))
    .POST(HttpRequest.BodyPublishers.ofString("{\"key\":\"value\"}"))
    .build();

BodyPublishers 类型:

  • ofString() - 从字符串创建请求体

  • ofByteArray() - 从字节数组创建请求体

  • ofFile() - 从文件创建请求体

  • noBody() - 无请求体


3. HttpResponse

表示接收到的 HTTP 响应。

处理响应体:

  • body() - 获取响应体

  • BodyHandlers 用于处理响应体:

    • ofString() - 将响应体作为字符串

    • ofByteArray() - 将响应体作为字节数组

    • ofFile() - 将响应体写入文件

    • discarding() - 丢弃响应体

同步请求示例

java 复制代码
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println("Status code: " + response.statusCode());
System.out.println("Response body: " + response.body());

异步请求示例

java 复制代码
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com"))
    .build();

client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println)
    .join(); // 等待完成

WebSocket 支持

java 复制代码
HttpClient client = HttpClient.newHttpClient();

WebSocket webSocket = client.newWebSocketBuilder()
    .buildAsync(URI.create("ws://example.com/chat"), new WebSocket.Listener() {
        @Override
        public void onOpen(WebSocket webSocket) {
            System.out.println("WebSocket opened");
            webSocket.sendText("Hello", true);
            WebSocket.Listener.super.onOpen(webSocket);
        }
        
        @Override
        public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
            System.out.println("Received message: " + data);
            return WebSocket.Listener.super.onText(webSocket, data, last);
        }
    }).join();

高级特性

1. 多部分请求

java 复制代码
String boundary = "boundary";
HttpRequest request = HttpRequest.newBuilder()
    .header("Content-Type", "multipart/form-data; boundary=" + boundary)
    .POST(HttpRequest.BodyPublishers.ofByteArrays(Arrays.asList(
        "--boundary\r\nContent-Disposition: form-data; name=\"field1\"\r\n\r\nvalue1\r\n".getBytes(),
        "--boundary\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\nContent-Type: text/plain\r\n\r\nFile content\r\n".getBytes(),
        "--boundary--\r\n".getBytes()
    )))
    .build();

2. 处理响应流

java 复制代码
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com/large-file"))
    .build();

HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());

try (InputStream is = response.body()) {
    // 处理输入流
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = is.read(buffer)) != -1) {
        // 处理数据块
    }
}

3. 请求拦截器

java 复制代码
HttpClient client = HttpClient.newBuilder()
    .executor(Executors.newFixedThreadPool(5))
    .authenticator(new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("user", "password".toCharArray());
        }
    })
    .build();

最佳实践

  1. 重用 HttpClient:HttpClient 是线程安全的,应该重用而不是为每个请求创建新实例

  2. 处理超时:总是设置合理的连接和请求超时

  3. 错误处理:正确处理 HTTP 错误状态码和异常

  4. 资源管理:确保关闭响应体和输入流

  5. 性能考虑:对于大量请求,考虑使用异步模式

java.net.http 包提供了现代 HTTP 客户端所需的所有功能,是 Java 应用程序中进行 HTTP 通信的首选方式。

相关推荐
怪奇云呼军1 小时前
闪电智能VoiceAgent 如何管理呼入、接听、桥接和挂断状态?
java·前端·网络·数据库·人工智能
IT机器猫1 小时前
RabbitMQ基础二
java·spring boot·分布式·spring cloud·log4j·rabbitmq·springamqp
卷心菜的学习路2 小时前
基于 Spring Cloud Tencent 元数据路由实现个人开发泳道,告别频繁部署
java·spring cloud
xieliyu.2 小时前
UPD协议结构以及开发中注意事项
java·开发语言·笔记·java-ee
张宇Joaquin2 小时前
openEuler编译和更换内核的方法
java·linux·服务器
程序员黑豆2 小时前
Java正则表达式详解
java·前端·ai编程
Flynt3 小时前
我试了Spring Boot 4的原生镜像,聊聊那些数字和坑
java·spring boot
M-Robots echo10 小时前
轻量化裁剪方案解析:M-Robots 模块化构建,适配高低端各类机器人硬件平台
java·机器人·ros·开源社区·atomgit·m-robots
不可求~11 小时前
多模型路由怎么落地:把任务分流写进项目的最小实现
java·前端·数据库
mldong12 小时前
用 DDD 设计工作流引擎:聚合根与充血模型
java·架构