| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- 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 配置项示例
- *
- * <p>通过 {@code HttpClient.newBuilder()} 返回的 Builder 可以配置客户端的
- * 通用行为,主要配置项如下:</p>
- *
- * <table>
- * <tr><th>配置项</th><th>作用</th><th>备注</th></tr>
- * <tr><td>version()</td><td>HTTP 协议版本</td><td>HTTP_1_1 / HTTP_2</td></tr>
- * <tr><td>connectTimeout()</td><td>连接建立超时时间</td><td>超过则抛 ConnectTimeoutException</td></tr>
- * <tr><td>executor()</td><td>异步请求使用的线程池</td><td>不设置则用内置默认线程池</td></tr>
- * <tr><td>followRedirects()</td><td>重定向策略</td><td>NEVER / ALWAYS / NORMAL</td></tr>
- * <tr><td>proxy()</td><td>代理选择器</td><td>NO_PROXY 直连</td></tr>
- * <tr><td>cookieHandler()</td><td>Cookie 管理器</td><td>配合 CookieManager 使用</td></tr>
- * <tr><td>authenticator()</td><td>认证器</td><td>配合 Authenticator 使用(Basic Auth 等)</td></tr>
- * <tr><td>sslContext/sslParameters()</td><td>TLS 配置</td><td>仅 HTTPS 生效</td></tr>
- * <tr><td>priority()</td><td>HTTP/2 流优先级</td><td>仅 HTTP_2 生效</td></tr>
- * </table>
- */
- public class ClientConfigExample {
- /** 服务基地址常量 */
- private static final String BASE_URL = "http://localhost:8080";
- /**
- * 构建一个携带多项配置的 HttpClient。
- *
- * <p>所有配置均为「在客户端创建时一次性设定」,创建后不可修改。</p>
- *
- * @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<String> 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());
- }
- }
- }
|