最近比较忙,很久一段时间没有写博文了。今天和大家一起学习一下在JAVA程序如何使用网络代理(Http、socks代理)。我想网络代理设置大家并不陌生,基本在每一个客户端程序都具备这个功能。闲话不多说,马上开始。老规矩先上我这些新学朋友最喜欢的地方:http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
在JAVA程序中要使用网络代理,有两种设置的方式:
一、在JAVA可视化控制面板中直接设置。如下图:
二、在程序中设置网络代理。
下面主要是讲述第二种方式如何在JAVA程序中设置网络代理。
在程序中设置网络代理又分为两种:
1)"全局"网络代理
所谓的“全局”,指的是一旦设置了代理,就会在整个程序中起作用。使用非常简单,
下面是设置Http代理:
System.setProperty("proxySet", "true"); System.setProperty("http.proxyHost", sProxyHost); System.setProperty("http.proxyPort", sProxyPort)
设置Socks代理:
System.setProperty("proxySet", "true"); System.setProperty("socksProxyHost", sProxyHost); System.setProperty("socksProxyPort", sProxyPort);
Ftp、Https代理也类似,详情可以登录官网看一下。这里主要针对常用的Http、Socks代理。
不过,值得注意的是使用这种方式,如果输入的sProxyHost和sProxyPort不匹配(也就是说代理不可用)时,系统不会有任何提示,同时它会使用本地的网络进行网络连接。所以这样就照成了一个问题,场景:假如你的电脑可以上网,但是你想你的程序使用某个代理进行登录,还不幸运,恰恰这时你输入的代理地址或者代理端口不正确,但是系统没有提示任何错误,而且成功登录,给大家的错觉大家可能会以为这个代理成功了。其实像上面的场景,代理并没有成功,只是使用了本地可用的网络连接。如何解决这种情况呢,下面会说到。
2) “局部”网络代理
所谓的"局部",指的是代理设置只在某个连接中起作用。
设置Http代理 (代码片段)
SocketAddress addr = new InetSocketAddress("122.72.88.85", 80); Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); URL url = new URL("http://www.google.com.tw"); URConnection conn = url.openConnection(proxy);
设置Socks代理(代码片段,来自官网)
SocketAddress addr = new InetSocketAddress("122.72.88.85", 1080); Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr); Socket socket = new Socket(proxy); InetSocketAddress dest = new InetSocketAddress("server.foo.com", 1234); socket.connect(dest);
3)用户验证。
在官网中也详细提到,这里不再累赘了。http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-auth.html
对于上面红色字体部分的解决方案: 先用“局部”网络代理的方式进行测试,测试这个代理地址和端口是否可用,如果代理成功就使用 "全局"网络代理的方式来设置网络代理。下面来个例子(以Http代理为例子,其他的代理也差不多):
import java.net.Authenticator; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.URL; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; /** * <code>ProxySettingSample</code> * * @author Jimmy(SZ) * * @since <i>May 25, 2013</i> */ public class ProxySettingSample { public static final String PRXOY_HOST = "122.129.120.172"; public static final String PROXY_PORT = "8080"; public static final String TEST_ADDRESS = "http://www.google.com.tw"; private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor(); /** * @param args */ public static void main(String[] args) { // 用户验证 if (args.length == 2) { Authenticator.setDefault(new LoginAuthenticator(args[0], args[1])); } Callable<Boolean> oCallback = new Callable<Boolean>() { @Override public Boolean call() throws Exception { HttpURLConnection oConn = null; try { Proxy oProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PRXOY_HOST, Integer.parseInt(PROXY_PORT))); URL url = new URL("http://www.aastocks.com"); oConn = (HttpURLConnection) url.openConnection(oProxy); oConn.setConnectTimeout(5000); oConn.connect(); } catch (Exception e) { e.printStackTrace(); // 如果报异常证明,代理设置不可用 return false; } finally { if (oConn != null) { oConn.disconnect(); } } return true; } }; FutureTask<Boolean> oTask = new FutureTask<Boolean>(oCallback) { @Override protected void done() { try { Boolean bCheckSuccess = (Boolean)this.get(); if (bCheckSuccess) { // 代理测试成功 System.err.println("代理成功"); // 测试成功后再使用"全局网络代理" System.setProperty("proxySet", "true"); System.setProperty("http.proxyHost", PRXOY_HOST); System.setProperty("http.proxyPort", PROXY_PORT); } else { //代理设置失败 System.err.println("无法连接到网络,请检查代理设置!!"); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }; EXECUTOR.submit(oTask); EXECUTOR.shutdown(); } static class LoginAuthenticator extends Authenticator { /** User name **/ private String m_sUser; /** Password **/ private String m_sPsw; public LoginAuthenticator(String sUser, String sPsw) { m_sUser = sUser; m_sPsw = sPsw; } public PasswordAuthentication getPasswordAuthentication() { return (new PasswordAuthentication(m_sUser, m_sPsw.toCharArray())); } } }
例子上面的PRXOY_HOST 和PROXY_PORT 是从网上找的Http代理服务器(http://51dai.li/http_fast.html)。