Java 语言发起 HTTP 代理请求代码示例

发布于 2026-02-07 | 作者: FreeProxy Team

在 Java 中发起 HTTP 代理请求不需要任何第三方库:JDK 自带的 HttpURLConnection 配合 java.net.Proxy 类,就能以连接为单位精确指定代理。除这种显式方式外,还可以通过系统属性做进程级全局代理,或用 ProxySelector 按目标地址动态选择节点。本文以 Proxy 类为主线讲解完整示例、认证与超时设置,并梳理各方案的适用边界。

环境准备与三种配置方式对比

JDK 8 及以上版本无需额外 jar 包,导入 java.net 包下的相关类即可开工。三种代理方式各有取舍,先做选型再动手:

  • Proxy 参数:url.openConnection(proxy) 只影响这一个连接,粒度最细,推荐作为默认方案。
  • 系统属性:设置 http.proxyHost 等属性后全局生效,适合一次性脚本或无法修改代码的场景。
  • ProxySelector:按目标地址返回不同代理,适合代理池与多出口调度。

使用 Proxy 类建立代理连接

Proxy.Type.HTTP 表示普通正向代理,地址与端口由 InetSocketAddress 指定。拿到 HttpURLConnection 后,connectTimeout 控制与代理建立连接的最长时间,readTimeout 控制读取数据的等待上限,二者相互独立,单位都是毫秒。目标 URL 协议是 https 时会自动经代理走 CONNECT 隧道,无需开发者额外处理 TLS 层面的问题。

完整代码示例

下面的例子通过 Proxy 打开连接,设置了双阶段超时并正确读取响应:

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class ProxyDemo {
    public static void main(String[] args) throws IOException {
        Proxy proxy = new Proxy(
                Proxy.Type.HTTP,
                new InetSocketAddress("127.0.0.1", 8080));

        URL url = new URL("https://httpbin.org/ip");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
        conn.setConnectTimeout(10_000);
        conn.setReadTimeout(15_000);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");

        int code = conn.getResponseCode();
        System.out.println("状态码: " + code);

        try (InputStream in = conn.getInputStream();
             Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)
                     .useDelimiter("\\A")) {
            System.out.println(scanner.hasNext() ? scanner.next() : "");
        } finally {
            conn.disconnect();
        }
    }
}

代码用 try-with-resources 关闭输入流,并在 finally 中断开连接。需要特别注意:getInputStream 在收到 4xx、5xx 响应时会抛出 IOException,此时应改读 getErrorStream 获取错误响应体,这是 HttpURLConnection 一个非常容易踩坑的细节。

代理认证与系统属性方式

代理返回 407 时需要认证。JDK 的标准做法是调用 Authenticator.setDefault 注册全局认证器,在回调里返回 PasswordAuthentication 对象;也可以手动拼接 Proxy-Authorization 请求头,值为 Basic 加上 Base64 编码的「用户名:密码」。系统属性方式则更省事:System.setProperty("http.proxyHost", "127.0.0.1") 与 setProperty("http.proxyPort", "8080"),或在启动命令追加 -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8080。HTTPS 流量对应 https.proxyHost 属性,http.nonProxyHosts 可以配置不走代理的例外清单。

常见异常与注意事项

  • ConnectException: Connection refused:代理地址或端口错误,先确认代理进程存活。
  • SocketTimeoutException: connect timed out:与代理握手超时,可能是网络链路不通或代理过载。
  • 407 与认证异常:账号密码错误,或代理要求先绑定出口 IP 白名单。
  • 响应乱码:按响应头 Content-Type 显式指定字符集读取,不要依赖平台默认编码。

Article ID: 34

(本文仅供技术交流,请遵守法律法规)

返回知识库
广告区域 (Ad Space)