本文主要讲述使用HttpClient时的代理设置。
常见的设置代理的方法
使用系统代理配置
可以通过下面的方式来分别设置HTTP代理,HTTPS代理和SOCKS代理:
// HTTP 代理,只能代理 HTTP 请求
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "9876");
// HTTPS 代理,只能代理 HTTPS 请求
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("https.proxyPort", "9876");
// SOCKS 代理,支持 HTTP 和 HTTPS 请求
// 注意:如果设置了 SOCKS 代理就不要设 HTTP/HTTPS 代理
System.setProperty("socksProxyHost", "127.0.0.1");
System.setProperty("socksProxyPort", "1080");
这里有三点要说明:
1.系统默认先使用 HTTP/HTTPS 代理,如果既设置了 HTTP/HTTPS 代理,又设置了 SOCKS 代理,SOCKS 代理会起不到作用
2.由于历史原因,注意 socksProxyHost 和 socksProxyPort 中间没有小数点
3.HTTP 和 HTTPS 代理可以合起来缩写,如下:
// 同时支持代理 HTTP/HTTPS 请求
System.setProperty("proxyHost", "127.0.0.1");
System.setProperty("proxyPort", "9876");
JVM 命令行参数
在VM arguments中填写参数:-DproxyHost=127.0.0.1 -DproxyPort=9876
HttpURLConnection 使用代理
HttpURLConnection 的 openConnection() 方法可以传入一个 Proxy 参数,如下:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 9876));
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection(proxy);
OK 了,就这么简单!
不仅如此,我们注意到 Proxy 构造函数的第一个参数为枚举类型 Proxy.Type.HTTP ,那么很显然,如果将其修改为 Proxy.Type.SOCKS 即可以使用 SOCKS 代理。
HttpClient 使用代理
由于 HttpClient 非常灵活,使用 HttpClient 来连接代理有很多不同的方法。最简单的方法莫过于下面这样:
HttpHost proxy = new HttpHost("127.0.0.1", 9876, "HTTP");
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(proxy, request);
使用RequestConfig类
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
request.setConfig(
RequestConfig.custom()
.setProxy(new HttpHost("45.32.21.237", 8888, "HTTP"))
.build()
);
CloseableHttpResponse response = httpclient.execute(request);
使用RoutePlanner类
HttpHost proxy = new HttpHost("127.0.0.1", 9876, "HTTP");
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
CloseableHttpClient httpclient = HttpClients.custom()
.setRoutePlanner(routePlanner)
.build();
HttpGet request = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(request);
使用系统代理
怎么在程序中自动使用系统代理呢?
对于 HttpURLConnection 类来说,程序不用做任何变动,它会默认使用系统代理。但是 HttpClient 默认是不使用系统代理的,如果想让它默认使用系统代理,可以通过 SystemDefaultRoutePlanner 和 ProxySelector 来设置。示例代码如下:
SystemDefaultRoutePlanner routePlanner = new SystemDefaultRoutePlanner(ProxySelector.getDefault());
CloseableHttpClient httpclient = HttpClients.custom()
.setRoutePlanner(routePlanner)
.build();
HttpGet request = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(request);
以上内容来自:Java 和 HTTP 的那些事(二) 使用代理
使用shadowsocks的代理说明
我有一台香港的windows服务器,在上面搭建了Shadowsocks服务,本地浏览器测试正常,但程序中使用System.setProperty和RequestConfig的方式都无效。
最后使用RoutePlanner类成功。