package space.anyi.httpClient; import java.io.IOException; import java.net.CookieManager; import java.net.ProxySelector; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.time.Duration; import java.util.concurrent.Executors; /** * HTTP Client 配置项示例 * *

通过 {@code HttpClient.newBuilder()} 返回的 Builder 可以配置客户端的 * 通用行为,主要配置项如下:

* * * * * * * * * * * * *
配置项作用备注
version()HTTP 协议版本HTTP_1_1 / HTTP_2
connectTimeout()连接建立超时时间超过则抛 ConnectTimeoutException
executor()异步请求使用的线程池不设置则用内置默认线程池
followRedirects()重定向策略NEVER / ALWAYS / NORMAL
proxy()代理选择器NO_PROXY 直连
cookieHandler()Cookie 管理器配合 CookieManager 使用
authenticator()认证器配合 Authenticator 使用(Basic Auth 等)
sslContext/sslParameters()TLS 配置仅 HTTPS 生效
priority()HTTP/2 流优先级仅 HTTP_2 生效
*/ public class ClientConfigExample { /** 服务基地址常量 */ private static final String BASE_URL = "http://localhost:8080"; /** * 构建一个携带多项配置的 HttpClient。 * *

所有配置均为「在客户端创建时一次性设定」,创建后不可修改。

* * @return 配置完善的 HttpClient */ public HttpClient buildConfiguredClient() { // Cookie 管理器(Index: CookieManager 负责保存/发送 Cookie) CookieManager cookieManager = new CookieManager(); return HttpClient.newBuilder() // 指定 HTTP 协议版本为 1.1(本服务仅支持 HTTP/1.1) .version(HttpClient.Version.HTTP_1_1) // 连接建立超过 5 秒未成功则失败 .connectTimeout(Duration.ofSeconds(5)) // 自定义异步任务的执行线程池(默认是内置线程池) .executor(Executors.newFixedThreadPool(4)) // 重定向策略:NORMAL 只自动跟随「安全方法」的重定向 .followRedirects(HttpClient.Redirect.NORMAL) // 不使用代理,直连 .proxy(ProxySelector.getDefault()) // 配置 Cookie 管理器,自动管理会话 Cookie .cookieHandler(cookieManager) .build(); } /** * 构建启用 HTTP/2 的客户端(本服务不支持,仅演示配置写法)。 */ public HttpClient buildHttp2Client() { return HttpClient.newBuilder() .version(HttpClient.Version.HTTP_2) // priority 仅对 HTTP/2 生效,范围 1~256,越大优先级越高 .priority(256) .build(); } /** * 使用配置好的客户端发送 GET 请求。 * * @return GET /api/users 的响应 */ public HttpResponse sendGet() throws IOException, InterruptedException { HttpClient httpClient = buildConfiguredClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(BASE_URL + "/api/users")) .GET() .build(); return httpClient.send(request, BodyHandlers.ofString()); } /** * 演示「连接超时」配置:连接不存在的地址应快速失败并抛异常。 */ public void demoConnectTimeout() { HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(2)) .build(); HttpRequest request = HttpRequest.newBuilder() // 使用一个不存在的端口,模拟连接超时 .uri(URI.create("http://localhost:9999")) .GET() .build(); try { client.send(request, BodyHandlers.ofString()); } catch (java.net.http.HttpConnectTimeoutException e) { System.out.println("连接超时: " + e.getMessage()); } catch (IOException | InterruptedException e) { System.out.println("请求异常: " + e.getMessage()); } } }