如何在Java JDK HttpClient中使用SOCKS5代理
问题原因
你当前代码报错的核心原因是:ProxySelector.of(InetSocketAddress) 方法默认生成的是HTTP类型代理的配置,你把HTTP代理的请求包发给SOCKS5代理的端口,服务端无法识别自然不会返回合法响应,就抛出了头部解析失败的异常。
JDK自带的java.net.http.HttpClient本身支持SOCKS5代理,只需要明确指定代理类型为SOCKS即可,以下是两种可行实现方案:
方案1:自定义ProxySelector指定SOCKS代理类型
不需要修改全局系统属性,仅对当前HttpClient实例生效,推荐使用:
import java.io.IOException; import java.net.*; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.Collections; import java.util.List; public class ProxyApp { public static void main(String[] args) throws Exception { run1(); } public static void run1() throws Exception { // 自定义ProxySelector,返回SOCKS类型的代理实例 ProxySelector proxySelector = new ProxySelector() { @Override public List<Proxy> select(URI uri) { Proxy socksProxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("localhost", 8181)); return Collections.singletonList(socksProxy); } @Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { throw new RuntimeException("SOCKS代理连接失败", ioe); } }; HttpClient client = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1) .proxy(proxySelector) .build(); HttpRequest request = HttpRequest .newBuilder(new URI("http://example.org/")) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); String verificationText = "Example Domain"; // 运行成功应输出"true",否则代表请求失败 System.out.println(response.body().contains(verificationText)); } }
方案2:通过系统属性配置全局SOCKS代理
如果要对所有JDK网络请求生效,可以直接配置SOCKS全局代理,不需要修改HttpClient的构建逻辑:
启动命令添加参数
java -DsocksProxyHost=localhost -DsocksProxyPort=8181 ProxyApp
代码内动态设置(需要在HttpClient实例构建前执行)
System.setProperty("socksProxyHost", "localhost"); System.setProperty("socksProxyPort", "8181");
内容的提问来源于stack exchange,提问作者Devabc
相关产品推荐
相关产品推荐

