HttpClient怎么用?

wen python案例 1

本文目录导读:

HttpClient怎么用?

  1. 环境要求与引入
  2. 核心组件介绍
  3. 基本用法(同步 GET 请求)
  4. 发送 POST 请求(带 JSON 请求体)
  5. 异步请求(非阻塞)
  6. 处理不同类型的响应体
  7. 设置超时与代理
  8. 常见错误与注意事项

HttpClient 是 Java 11 开始官方内置的一个强大且现代的 HTTP 客户端库,用于替代传统的 HttpURLConnection,它支持 HTTP/1.1、HTTP/2、WebSocket,并提供了同步和异步两种模式。

以下是详细的用法指南,分为环境要求基本使用高级特性

环境要求与引入

  • Java版本:需要 Java 11 或更高版本。
  • 引入方式:不需要导入任何第三方依赖,它是 java.net.http 包下的标准库。
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

核心组件介绍

  • HttpClient:发送请求的客户端,可以单例复用,通常全局只创建一个。
  • HttpRequest:描述要发送的请求(URL、请求头、请求体、HTTP方法)。
  • HttpResponse<T>:描述服务器返回的响应(状态码、响应头、响应体)。

基本用法(同步 GET 请求)

这是最基础、最常见的用法。

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建一个 HttpClient 实例(通常是单例)
        HttpClient client = HttpClient.newHttpClient();
        // 2. 构建一个 GET 请求
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("https://api.github.com/users/octocat"))
                // .header("User-Agent", "Java HttpClient") // 可选:设置请求头
                .GET() // 显式指定方法,也可以不写(默认GET)
                .build();
        // 3. 发送请求,并接收响应(同步阻塞)
        // HttpResponse.BodyHandlers.ofString() 表示将响应体转为字符串
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        // 4. 处理响应
        System.out.println("Status Code: " + response.statusCode());
        System.out.println("Headers: " + response.headers().map());
        System.out.println("Body: " + response.body());
    }
}

发送 POST 请求(带 JSON 请求体)

如果你需要向服务器提交数据。

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientPostDemo {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        // JSON 请求体
        String jsonBody = "{\"name\": \"John\", \"age\": 30}";
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("https://httpbin.org/post"))
                .header("Content-Type", "application/json") // 设置内容类型
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody)) // 发布请求体
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}

异步请求(非阻塞)

如果你不想让当前线程等待网络请求,可以使用 sendAsync

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
public class HttpClientAsyncDemo {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://httpbin.org/delay/5")) // 模拟延迟5秒
                .GET()
                .build();
        // 发送异步请求,返回 CompletableFuture
        CompletableFuture<HttpResponse<String>> future = 
            client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        // 设置回调:当请求完成时打印结果
        future.thenApply(HttpResponse::body)
              .thenAccept(System.out::println);
        // 可以做其他事情...
        System.out.println("请求已经发出,主线程继续执行...");
        // 等待异步任务完成(防止程序立即退出)
        future.get(); 
    }
}

处理不同类型的响应体

HttpResponse.BodyHandlers 提供了多种处理响应体的方式:

处理器方法 返回值类型 适用场景
ofString() String 文本响应(HTML, JSON)
ofByteArray() byte[] 二进制数据(图片,文件)
ofInputStream() InputStream 大文件流式下载
ofFile(Path) Path 直接保存到文件
discarding() Void 不关心响应体

示例:下载图片到文件

import java.nio.file.Path;
import java.net.http.HttpResponse;
// ... 省略 client 和 request 构建
HttpResponse<Path> response = client.send(request, 
    HttpResponse.BodyHandlers.ofFile(Path.of("image.png")));
System.out.println("图片已保存到: " + response.body());

设置超时与代理

构建 HttpClient 和 HttpRequest 时可以配置超时。

import java.time.Duration;
import java.net.ProxySelector;
import java.net.InetSocketAddress;
HttpClient client = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(10)) // 连接超时
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 8080))) // 代理设置
        .followRedirects(HttpClient.Redirect.NORMAL) // 自动重定向
        .build();
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://example.com"))
        .timeout(Duration.ofSeconds(30)) // 请求超时(读取超时)
        .GET()
        .build();

常见错误与注意事项

  1. URI 格式:需要使用 URI 对象,而不是字符串,注意 URI 必须是绝对路径(包含协议头 http://https://)。
  2. 异常处理
    • send() 会抛出 IOException(网络问题)和 InterruptedException
    • sendAsync()CompletableFuture 会包含 ExecutionException
  3. HTTP/2 支持HttpClient 默认优先使用 HTTP/2,如果服务器不支持,会降级到 HTTP/1.1,这是自动的。
  4. 复用 HttpClientHttpClient 是线程安全的,建议在整个应用中使用单例,而不是每次请求都创建新的实例。
  5. Cookie 管理:默认不存储 Cookie,如果需要,可以在构建 HttpClient 时设置 CookieManager
  • 同步send(),简单直接,适合快速开发。
  • 异步sendAsync() + CompletableFuture,适合高并发、非阻塞场景。
  • Builder 模式HttpClient.newBuilder()HttpRequest.newBuilder() 用于灵活配置。

如果还有特定场景(比如文件上传、WebSocket 连接)的需求,可以进一步提问。

抱歉,评论功能暂时关闭!