Java 11+ 自带 HttpClient 发送 GET 请求需三步:构建 HttpClient 实例、用 HttpRequest.newBuilder() 创建请求并调用 .GET().uri(URI.create("url"))、通过 client.send() 同步获取 HttpResponse;须显式处理 IOException 和 InterruptedException,URL 参数需用 URLEncoder.encode() 编码,响应体乱码时应显式指定字符集。

Java 11+ 自带 HttpClient 怎么发 GET 请求
Java 11 起,java.net.http.HttpClient 成为标准库一部分,无需额外依赖。它比 HttpURLConnection 更简洁,比第三方库(如 OkHttp)更轻量,适合基础场景。
核心三步:构建 HttpClient 实例 → 构建 HttpRequest → 调用 send() 并处理响应。
常见错误是忽略异常类型:send() 抛出 IOException 和 InterruptedException,必须显式处理,不能只 catch Exception。
示例:
立即学习“Java免费学习笔记(深入)”;
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.build();
<p>HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("<a href="https://www.php.cn/link/4d2fe2e8601f7a8018594d98f28706f2">https://www.php.cn/link/4d2fe2e8601f7a8018594d98f28706f2</a>"))
.GET()
.build();</p><p>HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());</p><p>System.out.println(response.statusCode()); // 200
System.out.println(response.body()); // JSON 响应体
怎么设置超时和重试逻辑
超时必须显式配置,否则默认无连接/读取超时,可能无限阻塞。注意:connectTimeout 只控制建连阶段,不控制整个请求生命周期。
重试需手动实现,HttpClient 不内置重试机制。简单重试可套一层循环 + 异常判断,但要注意避免幂等性问题(GET 一般安全,POST 则要谨慎)。
-
HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(3)):仅作用于 TCP 连接建立 - 读取超时靠
HttpRequest.Builder.timeout()控制,例如.timeout(Duration.ofSeconds(10)) - 重试建议加退避(如
Thread.sleep(100 * (i + 1))),并限制最大重试次数(如 3 次) - 捕获
IOException(网络失败、连接中断)可重试;InterruptedException应传播或恢复中断状态
怎么处理中文 URL 或带参数的 GET 请求
URL 中含中文、空格、特殊字符必须编码,否则抛 URISyntaxException。别手拼字符串,用 URLEncoder.encode() 编码参数值,再组装;或更稳妥地用 UriBuilder(需引入 Jakarta EE API)——但纯 JDK 场景推荐手动编码。
示例(JDK 原生):
String baseUrl = "https://www.php.cn/link/4d2fe2e8601f7a8018594d98f28706f2"; String paramValue = "你好 world+test"; String encoded = URLEncoder.encode(paramValue, StandardCharsets.UTF_8); URI uri = URI.create(baseUrl + "?q=" + encoded); <p>HttpRequest request = HttpRequest.newBuilder() .uri(uri) .build();
注意:URLEncoder.encode() 会把空格转成 +,符合 application/x-www-form-urlencoded 规范,但 GET 请求中部分服务也接受 %20;只要服务端能解析,两者都可。别对整个 URL 调用 encode(),只编码参数值。
为什么响应体为空或乱码
常见原因是没指定字符集,HttpResponse.BodyHandlers.ofString() 默认用 UTF-8 解码,但若响应头 Content-Type 声明了其他编码(如 ISO-8859-1),就会乱码。
解决方法分两步:
- 先检查
response.headers().firstValue("content-type"),看是否含charset= - 用
BodyHandlers.ofString(StandardCharsets.UTF_8)显式传入正确编码,或动态提取 charset 后构造Charset - 如果响应体始终为空,确认服务端是否返回了
Content-Length: 0或Transfer-Encoding: chunked且 body 真为空 - 调试时可用
response.body().length()和response.headers().map()打印原始信息,排除网络拦截或代理干扰
真正麻烦的是某些老服务返回的 header 不规范(比如缺失 charset、写错大小写),这时候得 fallback 到字节数组处理,再按经验 guess 编码。


















