JAVA网络代理(Http、Socks等代理)

     最近比较忙,很久一段时间没有写博文了。今天和大家一起学习一下在JAVA程序如何使用网络代理(Http、socks代理)。我想网络代理设置大家并不陌生,基本在每一个客户端程序都具备这个功能。闲话不多说,马上开始。老规矩先上我这些新学朋友最喜欢的地方:http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html

       在JAVA程序中要使用网络代理,有两种设置的方式:

一、在JAVA可视化控制面板中直接设置。如下图:


JAVA网络代理(Http、Socks等代理)
这种方式就不多说了,很直观明了。

二、在程序中设置网络代理。

     下面主要是讲述第二种方式如何在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)。

 

你可能感兴趣的:(java)