一概述
本文介绍两种proxy的配置方式以及读取方式的java代码实现
项目中配置Proxy用到了两种方式
1
配置代理服务器
2
使用自动配置脚本,也就是配置pac方式
两种方式的目的都是给本机配置代理服务器,而第二种方式在配置策略上更加灵活
无论使用哪种代理方式,我们讨论的代理类型都为以下三个方式:
DIRECT, HTTP(PROXY), SOCKS
二配置代理服务器
1通过手动方式配置代理服务器.
优点:简单,直观
缺点:适配性差,无法实现策略匹配
2设定规则:
- 当同时设定了HTTP和套接字(SOCKET)代理方式,优先读取到HTTP代理
- 只有当只设定了SOCKET代理方式,通过代码才能读取到Proxy的type为SOCKS
3读取代理地址方式:
List<String> uriList =newArrayList<String>();//加入不同协议去获取不同的代理的ip,port,type三个参数
//proxytype:http时为Proxy.Type.HTTP,socket时为Proxy.Type.SOCKS
uriList.add("http://www.etnet.com.hk");
uriList.add("socket://www.etnet.com.hk");//只有只设定了套接字代理才能读到
for (String uri : uriList) {//遍历两种协议地址
if
(isSet) {
break;
}
try
{
//ProxySelector的使用方法在http://blog.csdn.net/ustcefish/article/details/41680907
//有说明,用于读取proxy的信息
l = ProxySelector.getDefault().select(new
java.net.URI(uri));
}
catch (URISyntaxException e1) {
e1.printStackTrace();
}
for
(Iterator<Proxy> iter = l.iterator();iter.hasNext();) {
Proxy proxy = iter.next();
InetSocketAddress iNetAddr= (InetSocketAddress) proxy.address();
if
(iNetAddr ==null) {
//com.etnet.utilities.LogUtils.log.info(this,"No
Proxy");
// System.out.println("detected
IE has NoProxy");
// NEED_PROXY = false;
}
else {
// NEED_PROXY = true;
if
(proxy.type() ==Proxy.Type.SOCKS) {
proxyHost
=iNetAddr.getHostName();
proxyPort
=iNetAddr.getPort();
proxyType
="SOCKS";
System.out.println("Found
a SOCKS proxyIP:port=" +proxyHost
+":" +proxyPort);
isSet =
true;
break;
}
if
(proxy.type() ==Proxy.Type.HTTP) {
proxyHost
=iNetAddr.getHostName();
proxyPort
=iNetAddr.getPort();
proxyType
="HTTP";
System.out.println("Found
a HTTP proxyIP:port=" +proxyHost
+":" +proxyPort);
isSet =
true;
break;
}
}
}
// end for
}
三通过自动脚本pac文件设置代理
1通过自动脚本pac文件代理服务器.
优点:适配性强,灵活,可以通过策略实现访问不同域名使用不同代理服务器
缺点:需要了解js脚本
2设定规则:
需要自己写一个js脚本(比如"file://d:/proxy.pac")实现代理服务器选择的不同策略,然后按最上面一个图导入,具体规则请google一下
3读取代理地址方式:
需要导入jre的lib/deploy.jar这个包
BrowserProxyInfo b =
newBrowserProxyInfo();
b.setType(ProxyType.AUTO);
b.setAutoConfigURL("file://d:/proxy.pac");
DummyAutoProxyHandler handler =
newDummyAutoProxyHandler();
try
{
handler.init(b);
}
catch (ProxyConfigException e1) {
//TODO
Auto-generated catch block
e1.printStackTrace();
}
URL url;
try
{
// need add socket
url =
new URL("http://www.etnet.com.hk");
ProxyInfo[] ps =handler.getProxyInfo(url);
for
(ProxyInfo p : ps) {
String[] info =p.toString().split(":");
proxyHost
= info[0];
proxyPort
= Integer.parseInt(info[1]);
}
}
catch (MalformedURLException e) {
//TODO
Auto-generated catch block
e.printStackTrace();
}
四 HTTP链接中使用Proxy
第二部分和第三部分我们知道怎么获取到proxy的信息,第四第五部分我们来看看在HTTP连接和TCP连接时我们如何使用之前获取到的Proxy信息。
- 组建一个proxy实例
publicstaticvoid
constructProxy() {
try
{
InetSocketAddress iNetAddr =
new InetSocketAddress(proxyHost,proxyPort);
if
("SOCKS".equals(proxyType))
{
httpProxy
=new Proxy(Proxy.Type.SOCKS,
iNetAddr);
}
elseif
("HTTP".equals(proxyType))
{
httpProxy
=new Proxy(Proxy.Type.HTTP,
iNetAddr);
}
}
catch (IllegalArgumentException ex) {
}
}
- 通过Authenticator完成代理的验证
publicstaticclass
CustomAuthenticatorextends Authenticator {
private
StringuserName ="";
private
Stringpassword ="";
public
CustomAuthenticator(StringuserName, String password) {
super();
this.userName
= userName;
this.password
= password;
}
// Called when password authorization is needed
protected
PasswordAuthenticationgetPasswordAuthentication(){
returnnew
PasswordAuthentication(userName,password);
}
}
Authenticator.setDefault(newCustomAuthenticator(prouser,
propass));//关键代码,穿透proxy密码验证
- 建立http连接
urlConnection=(HttpURLConnection)url.openConnection(httpProxy);
五 TCP链接中使用Proxy
- 和上面一样组建Proxy实例
- 通过Authenticator完成代理的验证
- 建立tcp链接
代码如下:
if (proxy !=null)
tcpSocket
=new Socket(proxy);
Authenticator.setDefault(newCustomAuthenticator(proxyUserName,proxyUserPass));
InetSocketAddress inet =
new InetSocketAddress(IP,PORT);
tcpSocket.connect(inet,TCPCONNECT_TIMEOUT);