Java HttpClient使用手册

发布于:2025-07-23 ⋅ 阅读:(17) ⋅ 点赞:(0)

在 Java 中,java.net.http.HttpClient 是一个现代化的 HTTP 客户端,自 Java 11 起引入,用于替代旧的 HttpURLConnection。它支持 HTTP/1.1 和 HTTP/2,提供异步非阻塞 API,并支持流式处理请求和响应。

1. 创建 HttpClient 实例

import java.net.http.HttpClient;
import java.time.Duration;

// 创建默认配置的HttpClient
HttpClient client = HttpClient.newHttpClient();

// 自定义配置的HttpClient
HttpClient customClient = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)        // 使用HTTP/2
    .followRedirects(HttpClient.Redirect.NORMAL) // 自动重定向
    .connectTimeout(Duration.ofSeconds(10))   // 连接超时
    .build();

2. 发送 GET 请求(同步)

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

// 构建GET请求
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/data"))
    .header("User-Agent", "Java HttpClient")
    .build();

// 发送请求并获取响应
try {
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println("状态码: " + response.statusCode());
    System.out.println("响应体: " + response.body());
} catch (Exception e) {
    e.printStackTrace();
}

带参数的HTTP GET请求示例如下:

将参数键值对编码后用&连接,添加到 URL 的?后面:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class HttpClientGetExample {
    public static void main(String[] args) throws Exception {
        // 参数键值对
        String param1 = "value1";
        String param2 = "特殊字符!@#$";

        // 构建查询字符串(手动编码参数)
        String query = String.format("param1=%s&param2=%s",
            URLEncoder.encode(param1, StandardCharsets.UTF_8),
            URLEncoder.encode(param2, StandardCharsets.UTF_8)
        );

        // 拼接完整URL
        String url = "https://api.example.com/data?" + query;

        // 创建HTTP请求
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .GET()  // 可省略,默认是GET
            .build();

        // 发送请求
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
            .thenApply(HttpResponse::body)
            .thenAccept(System.out::println)
            .join();
    }
}

 

3. 发送 POST 请求(带 JSON)

import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

// 请求JSON数据
String jsonBody = """
    {
        "name": "John",
        "age": 30
    }
    """;

// 构建POST请求
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/submit"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody, StandardCharsets.UTF_8))
    .build();

// 发送请求
try {
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println("状态码: " + response.statusCode());
    System.out.println("响应体: " + response.body());
} catch (Exception e) {
    e.printStackTrace();
}

4. 处理响应体为文件

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.nio.file.Paths;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com/file.zip"))
    .build();

try {
    Path filePath = Paths.get("downloaded_file.zip");
    HttpResponse<Path> response = client.send(
        request, 
        HttpResponse.BodyHandlers.ofFile(filePath)
    );
    System.out.println("文件下载完成: " + filePath);
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

5. 异步请求处理

import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/large-data"))
    .build();

// 异步发送请求
CompletableFuture<HttpResponse<String>> future = client.sendAsync(
    request, 
    HttpResponse.BodyHandlers.ofString()
);

// 处理完成后的回调
future.thenApply(HttpResponse::body)
    .thenAccept(body -> System.out.println("异步响应: " + body))
    .exceptionally(ex -> {
        System.err.println("请求失败: " + ex.getMessage());
        return null;
    });

// 主线程可以继续执行其他任务
System.out.println("主线程继续执行...");

 

关键类说明:

  • HttpClient:用于构建和配置 HTTP 客户端实例。
  • HttpRequest:用于构建 HTTP 请求,支持链式调用设置 URL、方法、头信息和请求体。
  • HttpResponse:表示 HTTP 响应,包含状态码、头信息和响应体。
  • BodyHandlers:用于处理响应体的静态工厂方法(如ofString()ofFile()ofByteArray()等)。
  • BodyPublishers:用于构建请求体的静态工厂方法(如ofString()ofFile()等)。

注意事项:

  1. 异常处理:同步请求需处理IOExceptionInterruptedException,异步请求通过exceptionally()处理异常。
  2. HTTP/2 支持:默认启用 HTTP/2,但服务器需支持才能使用。
  3. 异步编程:使用CompletableFuture处理异步操作,避免阻塞主线程。

网站公告

今日签到

点亮在社区的每一天
去签到