跳到正文
本中心目录
代码示例

Java HttpClient 代理接入示例

使用 JDK HttpClient、ProxySelector、代理认证和超时完成 HTTPS 请求。

只只HTTP技术团队维护更新于 2026年7月31日

JDK 11 及以上可直接使用标准库 java.net.http.HttpClient,无需为基础 HTTP 代理访问增加第三方客户端。

前置条件

  • 运行环境使用 JDK 11 或更高版本。
  • 通过受控环境注入 PROXY_HOSTPROXY_PORTPROXY_USERNAMEPROXY_PASSWORD
  • 代理密码只保留在进程环境或密钥服务中。

完整示例

Java
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,也不要在异常日志中输出环境变量。代理身份变化时创建新的客户端,避免旧连接继续携带原认证状态。

这篇内容解决了你的问题吗?

反馈只用于改进公开文档,不会提交账号或请求信息。