在內(nèi)網(wǎng)環(huán)境,有些時候需要設(shè)置Java代理,常見的有HTTP(s)代理和Socks代理,如何設(shè)置代理,Java 可以通過命令行參數(shù)設(shè)置,也可以在代碼級別上設(shè)置。
Http形式的命令行設(shè)置如下,該設(shè)置系統(tǒng)級別的代理。
-Dhttp.proxyHost=<proxy host>
-Dhttp.proxyPort=<proxy port>
-Dhttp.nonProxyHosts=<localhost|*.local.com>
其中:
-
proxyHostHttp代理服務(wù)器主機 -
proxyPortHttp代理服務(wù)器端口,默認80 -
nonProxyHosts不使用Http代理的地址,使用|分割地址,*表示地址通配符.
e.g. 設(shè)置Http代理服務(wù)器
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=3128 com.riverlcn.networking.proxies.CommandLineProxyDemo
大部分HTTP代理,都有用戶名和密碼認證,Java沒有直接提供設(shè)置用戶名和密碼的參數(shù),需要在初始化代碼中,設(shè)置Authenticator認證所需的用戶名和密碼。
private void initializeProxyAuthenticator() {
final String proxyUser = System.getProperty("http.proxyUser");
final String proxyPassword = System.getProperty("http.proxyPassword");
if (proxyUser != null && proxyPassword != null) {
Authenticator.setDefault(
new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
proxyUser, proxyPassword.toCharArray()
);
}
}
);
}
}
然后,可以設(shè)置如下代理認證的用戶名和密碼。
-Dhttp.proxyUser=<proxy user>
-Dhttp.proxyPassword=<proxy password>
當(dāng)然,我們可以在代碼中,設(shè)置代理的參數(shù)。e.g
// 設(shè)置代理
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "3128");
URL url = new URL(RESOURCE_URL);
URLConnection con = url.openConnection();
// 代理使用完成后,取消代理
System.setProperty("http.proxyHost", null);
上面設(shè)置,都是系統(tǒng)級別的,如果是單個調(diào)用級別的代理,可以這樣設(shè)置
// 設(shè)置代理
Proxy webProxy
= new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128));
// 使用代理
URL weburl = new URL("www.google.com");
HttpURLConnection webProxyConnection
= (HttpURLConnection) weburl.openConnection(webProxy);
// 不使用代理
HttpURLConnection directConnection
= (HttpURLConnection) weburl.openConnection(Proxy.NO_PROXY);
類似的Socks代理,可以通過命令行參數(shù)設(shè)置,如下
-DsocksProxyHost=<proxy host>
-DsocksProxyPort=<proxy port>
設(shè)置認證的用戶名和密碼同HTTP代理設(shè)置,當(dāng)然Socks代理支持單個調(diào)用,示例如下:
// HTTP協(xié)議,使用代理
Proxy socksProxy
= new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080));
HttpURLConnection socksConnection
= (HttpURLConnection) weburl.openConnection(socksProxy);
// TCP協(xié)議,使用代理
Socket proxySocket = new Socket(socksProxy);
InetSocketAddress socketHost
= new InetSocketAddress(SOCKET_SERVER_HOST, SOCKET_SERVER_PORT);
proxySocket.connect(socketHost);
HTTP代理認證流程
有些代理服務(wù)器,需要認證,HTTP 代理服務(wù)器認證流程:

解釋圖中的流程:
In this example, the Java client is sending an HTTP request to an external web server. By specifying the Java system properties identified above, the client connects to proxy server. The proxy server sends a request back to the client for credentials. The client provides the credentials and the proxy server authenticates the client. If authentication is successful, the proxy server forwards the request to the external server. The external server sends the response back to the proxy server which in turn sends the response to the client.
解決方案是:
When a proxy server requires authentication, it responds to connection requests with a credential request. In Java, this is handled by setting a default authenticator. There are numerous authentication types that are supported by Java. In this example, we will be using a simple username and password authenticator.
Add the following code to your client and initialize the proxy authenticator before creating any connections: