在内网环境,有些时候需要设置Java代理,常见的有HTTP(s)代理和Socks代理,如何设置代理,Java 可以通过命令行参数设置,也可以在代码级别上设置。
Http形式的命令行设置如下,该设置系统级别的代理。
-Dhttp.proxyHost=<proxy host>
-Dhttp.proxyPort=<proxy port>
-Dhttp.nonProxyHosts=<localhost|*.local.com>
其中:
-
proxyHost
Http代理服务器主机 -
proxyPort
Http代理服务器端口,默认80 -
nonProxyHosts
不使用Http代理的地址,使用|
分割地址,*
表示地址通配符.
e.g. 设置Http代理服务器
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=3128 com.riverlcn.networking.proxies.CommandLineProxyDemo
大部分HTTP代理,都有用户名和密码认证,Java没有直接提供设置用户名和密码的参数,需要在初始化代码中,设置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()
);
}
}
);
}
}
然后,可以设置如下代理认证的用户名和密码。
-Dhttp.proxyUser=<proxy user>
-Dhttp.proxyPassword=<proxy password>
当然,我们可以在代码中,设置代理的参数。e.g
// 设置代理
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);
上面设置,都是系统级别的,如果是单个调用级别的代理,可以这样设置
// 设置代理
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代理,可以通过命令行参数设置,如下
-DsocksProxyHost=<proxy host>
-DsocksProxyPort=<proxy port>
设置认证的用户名和密码同HTTP代理设置,当然Socks代理支持单个调用,示例如下:
// HTTP协议,使用代理
Proxy socksProxy
= new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080));
HttpURLConnection socksConnection
= (HttpURLConnection) weburl.openConnection(socksProxy);
// TCP协议,使用代理
Socket proxySocket = new Socket(socksProxy);
InetSocketAddress socketHost
= new InetSocketAddress(SOCKET_SERVER_HOST, SOCKET_SERVER_PORT);
proxySocket.connect(socketHost);
HTTP代理认证流程
有些代理服务器,需要认证,HTTP 代理服务器认证流程:
img解释图中的流程:
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:
网友评论