Java HttpClient 代理接入示例
使用 JDK HttpClient、ProxySelector、代理认证和超时完成 HTTPS 请求。
只只HTTP技术团队维护更新于 2026年7月31日
JDK 11 及以上可直接使用标准库 java.net.http.HttpClient,无需为基础 HTTP 代理访问增加第三方客户端。
前置条件
- 运行环境使用 JDK 11 或更高版本。
- 通过受控环境注入
PROXY_HOST、PROXY_PORT、PROXY_USERNAME和PROXY_PASSWORD。 - 代理密码只保留在进程环境或密钥服务中。
完整示例
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
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.time.Duration;
public final class ProxyExample {
/**
* 使用 JDK HttpClient 通过账密代理请求公开出口检测地址。
*/
public static void main(String[] args) throws Exception {
String proxyHost = System.getenv("PROXY_HOST");
int proxyPort = Integer.parseInt(System.getenv("PROXY_PORT"));
String proxyUsername = System.getenv("PROXY_USERNAME");
char[] proxyPassword = System.getenv("PROXY_PASSWORD").toCharArray();
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.proxy(ProxySelector.of(new InetSocketAddress(proxyHost, proxyPort)))
.authenticator(new Authenticator() {
/** 仅向代理服务器提供认证信息,避免响应目标站认证挑战。 */
@Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType() != RequestorType.PROXY) return null;
return new PasswordAuthentication(proxyUsername, proxyPassword);
}
})
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://<public-test-host>/ip"))
.timeout(Duration.ofSeconds(30))
.GET()
.build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
if (response.statusCode() >= 400) {
throw new IllegalStateException("HTTP " + response.statusCode());
}
System.out.println(response.body());
}
}
预期结果
- 客户端先连接代理,再为 HTTPS 目标建立隧道。
- 响应正文显示代理出口,状态码小于 400。
- 长生命周期服务应复用
HttpClient,保留连接池收益。
错误处理
- 407 表示代理认证未通过,检查用户名、密码和权益。
HttpConnectTimeoutException表示连接阶段超过 10 秒。- 目标状态码和代理连接异常必须分开记录。
安全提示
不要手工写入 Proxy-Authorization,也不要在异常日志中输出环境变量。代理身份变化时创建新的客户端,避免旧连接继续携带原认证状态。
这篇内容解决了你的问题吗?
反馈只用于改进公开文档,不会提交账号或请求信息。