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 通信的首选方式。

相关推荐
daidaidaiyu2 小时前
Spring BeanPostProcessor接口
java·spring
weixin_436525072 小时前
SpringBoot 单体服务集成 Zipkin 实现链路追踪
java·spring boot·后端
她说..2 小时前
Redis实现未读消息计数
java·数据库·redis·缓存
喵叔哟2 小时前
64.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--预算报表
微服务·架构·.net
book多得2 小时前
Redis 大 Key 问题:识别、危害与最优处理方案
java·redis·mybatis
任子菲阳3 小时前
学Java第四十三天——Map双列集合
java·开发语言
z2014z3 小时前
LitJSON 轻量级、高效易用的 .NET JSON 库 深度解析与实战指南
json·.net
zeijiershuai3 小时前
Java 会话技术、Cookie、JWT令牌、过滤器Filter、拦截器Interceptor
java·开发语言
fury_1234 小时前
tsfile.raw提示
java·前端·javascript