Java 11 HttpClient如何配置HTTP代理?连接测试与异常处理示例

Java 11开始提供标准的java.net.http.HttpClient,可以用于发送HTTP和HTTPS请求。

如果业务需要通过固定代理或长效代理访问公开接口,可以直接通过ProxySelector配置代理服务器。

本文演示:

Java HttpClient配置代理;

设置连接和请求超时;

处理代理认证;

判断常见异常;

复用HttpClient连接。

携趣官方长效代理提供固定IP和端口,支持HTTP(S)和S5协议,可直接配置在浏览器、软件或代码中。

一、配置不带账号密码的HTTP代理

import java.net.InetSocketAddress;

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 class HttpProxyDemo {

复制代码
public static void main(String[] args) throws Exception {
    String proxyHost = "127.0.0.1";
    int proxyPort = 8080;

    HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .proxy(
                    ProxySelector.of(
                            new InetSocketAddress(
                                    proxyHost,
                                    proxyPort
                            )
                    )
            )
            .build();

    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://httpbin.org/ip"))
            .timeout(Duration.ofSeconds(20))
            .header(
                    "User-Agent",
                    "Java-Proxy-Test/1.0"
            )
            .GET()
            .build();

    HttpResponse<String> response = client.send(
            request,
            HttpResponse.BodyHandlers.ofString()
    );

    System.out.println(response.statusCode());
    System.out.println(response.body());
}

}

二、配置代理账号和密码

如果代理使用账号密码认证,可以配置Authenticator:

import java.net.Authenticator;

import java.net.PasswordAuthentication;

Authenticator authenticator = new Authenticator() {

@Override

protected PasswordAuthentication

getPasswordAuthentication() {

return new PasswordAuthentication(

"proxyUsername",

"proxyPassword".toCharArray()

);

}

};

完整构建方式:

HttpClient client = HttpClient.newBuilder()

.connectTimeout(Duration.ofSeconds(10))

.proxy(

ProxySelector.of(

new InetSocketAddress(

proxyHost,

proxyPort

)

)

)

.authenticator(authenticator)

.build();

需要注意,不要将真实账号密码直接提交到Git仓库。

可以通过环境变量读取:

String username = System.getenv("PROXY_USERNAME");

String password = System.getenv("PROXY_PASSWORD");

三、白名单认证和账号密码认证怎么选?

常见代理认证方式包括:

公网IP白名单;

用户名和密码;

两者组合。

白名单方式适合公网IP固定的服务器。

如果运行环境是家庭宽带或者动态公网IP,白名单可能随公网IP变化而失效。携趣官方提供白名单管理和自动同步工具,用于处理动态公网IP变化导致的授权失效问题。

四、增加异常处理

import java.io.IOException;

import java.net.ConnectException;

import java.net.http.HttpConnectTimeoutException;

import java.net.http.HttpTimeoutException;

public class ProxyRequestService {

复制代码
private final HttpClient client;

public ProxyRequestService(
        String proxyHost,
        int proxyPort
) {
    this.client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .proxy(
                    ProxySelector.of(
                            new InetSocketAddress(
                                    proxyHost,
                                    proxyPort
                            )
                    )
            )
            .build();
}

public String get(String url)
        throws InterruptedException {

    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .timeout(Duration.ofSeconds(20))
            .GET()
            .build();

    try {
        HttpResponse<String> response =
                client.send(
                        request,
                        HttpResponse.BodyHandlers.ofString()
                );

        if (response.statusCode() == 407) {
            throw new IllegalStateException(
                    "代理认证失败"
            );
        }

        if (response.statusCode() >= 500) {
            throw new IllegalStateException(
                    "服务端异常: "
                            + response.statusCode()
            );
        }

        return response.body();

    } catch (HttpConnectTimeoutException e) {
        throw new IllegalStateException(
                "连接代理服务器超时",
                e
        );

    } catch (HttpTimeoutException e) {
        throw new IllegalStateException(
                "请求响应超时",
                e
        );

    } catch (ConnectException e) {
        throw new IllegalStateException(
                "无法连接代理服务器",
                e
        );

    } catch (IOException e) {
        throw new IllegalStateException(
                "网络请求失败",
                e
        );
    }
}

}

五、不要为每个请求创建一个HttpClient

不推荐:

for (...) {

HttpClient client = HttpClient.newBuilder()

.proxy(...)

.build();

复制代码
client.send(...);

}

更合理的方式是复用HttpClient实例。

原因包括:

可以减少重复创建对象;

有利于复用底层连接;

配置统一;

更容易集中处理超时和认证;

便于后续增加日志和监控。

六、固定代理和动态代理的代码差异

固定代理:

创建HttpClient → 连续发送请求

短效动态代理:

调用代理API → 创建或更新代理配置 → 发送请求

Java标准HttpClient构建后,其代理选择器通常不会频繁变化。

如果需要高频切换代理,可以:

为每个代理维护一个HttpClient;

自定义动态ProxySelector;

使用Apache HttpClient;

使用固定入口的隧道代理。

总结

Java 11 HttpClient接入固定代理的关键步骤包括:

使用ProxySelector配置代理;

设置连接超时和请求超时;

根据需要配置认证;

识别407等代理相关状态;

复用HttpClient;

不在代码中暴露账号密码。

对于需要稳定固定出口的Java服务,可以使用长效代理;对于高频自动轮换需求,则应考虑动态代理管理或固定入口的隧道代理。

相关推荐
得物技术7 小时前
企业级 MultiAgent 的记忆系统:短期上下文与四层记忆架构实现|得物技术
java·人工智能·后端
撩得Android一次心动7 小时前
Kotlin 语言【知识点整理3】
java·开发语言·笔记·学习·kotlin
朝发如雪7 小时前
快速掌握Linux(4)(进程)
java·linux·服务器
2601_966949657 小时前
如何利用 1 分钟 K 线在 14:50 精准捕捉尾盘异动?Python 量化实战:1 分钟 K 线 + 全市场扫描
开发语言·人工智能·python·量化·quantdash·量化数据源
CarIise7 小时前
JavaScript基础语法与DOM操作实战课堂笔记
开发语言·javascript·笔记
JackSparrow4147 小时前
Kafka(七)集成Apache Avro+Apicurio Schema Registry以保障生产者与消费者的消息兼容性
java·中间件·rpc·kafka·apache·avro·schema-registry
林森lsjs7 小时前
零基础吃透二叉树:定义、遍历与高频算法 —数据结构柒
java·开发语言·数据结构·算法·二叉树
MacroZheng7 小时前
又一个神级画图Skill开源,再见draw.io!
java·人工智能·后端
2401_894915537 小时前
GEO 优化源码性能调优:高并发地域请求缓存与索引优化
java·服务器·网络·数据库·缓存
酒神dnspup7 小时前
SSL证书检测完整指南:用 DNSPup 排查过期、域名不匹配与 TLS 握手失败
网络·网络协议·http·ssl证书·http状态码