免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 819 | 回复: 0
打印 上一主题 下一主题

JAVA通过代理访问外部资源 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-02 14:52 |只看该作者 |倒序浏览

代码中通过代理访问外部资源
目前网络上最流行的协议就是HTTP协议。HTTP协议有许多优点,例如它能够穿越防火墙。同时HTTP也是很多其他协议的基础,例如SOAP协议就是建立在HTTP协议之上的。
Java通过两种API对HTTP提供支持,一种是servlet API,它覆盖了服务器端的编程问题;另一种是java.net包,它通过HttpURLConnection类在客户端提供了对HTTP协议的支持。但是我在使用servlet API的时候曾经遇到过一些问题。本文将介绍我曾遇到过的一些问题和相应的解决办法。
基础知识
通常在企业网络中,一个终端通过代理服务器同互联网连接起来,代理服务器负责监视网络流量和执行安全规则。在java.net API中,软件可以通过两个属性来支持代理服务器,它们分别是http.proxyHost和http.proxyPort。它们必须被设定为相应的代理服务器和端口,下面的代码展示了如何设定这两个属性:
String url = "http://www.digitalcq.com/",
   proxy = "proxy.digitalcq.com",
   port = "8080";
URL server = new URL(url);
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",proxy);
systemProperties.setProperty("http.proxyPort",port);
HttpURLConnection connection = (
    HttpURLConnection)server.openConnection();
connection.connect();
InputStream in = connection.getInputStream();
readResponse(in);
在上面的程序中,你需要根据实际情况设定代理服务器和端口。如果你不知道该如何设置的话,可以询问你们公司的网络管理员。
使用验证
通常公司会要求员工在连接到互联网之前登录到代理服务器。通过登录这种机制使公司可以更好的监控员工对互联网的使用,例如监控员工都访问了哪些网站。HttpURLConnection通过验证类支持代理服务器验证。下面是一个如何利用HttpURLConnection类进行验证的例子。首先需要实现一个验证者:
public class SimpleAuthenticator
   extends Authenticator
{
   private String username,
                  password;
    public SimpleAuthenticator(String username,String password)
   {
      this.username = username;
      this.password = password;
   }
    protected PasswordAuthentication getPasswordAuthentication()
   {
      return new PasswordAuthentication(
             username,password.toCharArray());
   }
}
然后,通过Authenticator.setDefault()方法注册验证者:
String url = "http://www.digitalcq.com/",
       proxy = "proxy.digitalcq.com",
       port = "8080",
       username = "usr",
       password = "pwd";
Authenticator.setDefault(new SimpleAuthenticator(
       username,password));
URL server = new URL(url);
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",proxy);
systemProperties.setProperty("http.proxyPort",port);
HttpURLConnection connection = (
    HttpURLConnection)server.openConnection();
connection.connect();
InputStream in = connection.getInputStream();
readResponse(in);
问题
上面介绍的都是HttpURLConnection类能够正常工作的情况。但是我在实际情况中遇到了一些网络,在这些网络中,HttpURLConnection类无法正常工作。最后我发现关键的问题在于使用了不正确的DNS配置。在实际情况中,HttpURLConnection类总是先尝试利用DNS服务器来解析地址名称。通常情况下,这种尝试会失败,而代理服务器会将连接重新定向。但是某些DNS服务器会返回一些不正确的响应,从而导致程序抛出UnknownHostException异常。作为一个程序员,系统不会为了你的程序更改DNS服务器的配置,因此你需要找出解决这个问题的方法。我的方案是通过自己实现HTTP协议来解决这个问题。例如一个GET命令可以用下面的代码来实现:
String url = "http://www.digitalcq.com/",
       proxy = "proxy.digitalcq.com",
       port = "8080",
       authentication = "usr:pwd";
URL server = new URL(url);
Socket socket = new Socket(proxy,port);
Writer writer = new OutputStreamWriter(socket.getOutputStream(),
                                       "US-ASCII");
writer.write("GET " + server.toExternalForm() + " HTTP/1.0\r\n");
writer.write("Host: " + server.getHost() + "\r\n");
writer.write("Proxy-Authorization: Basic "
             + new sun.misc.BASE64Encoder().encode(
               authentication.getBytes())
             + "\r\n\r\n");
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(
                            socket.getInputStream(),"US-ASCII"));
String line = reader.readLine();
if(line != null && line.startsWith("HTTP/"))
{
   int sp = line.indexOf(' ');
   String status = line.substring(sp + 1,sp + 4);
   if(status.equals("200"))
   {
      while(line.length() != 0)
         line = reader.readLine();
      readResponse(reader);
   }
   else
      throw new FileNotFoundException("Host reports error " +
                                       status);
}
else
   throw new IOException("Bad protocol");
reader.close();
writer.close();
socket.close();
在上面的代码中,大家可以注意到代理服务器的用户名和密码的格式是:
username:password,
并且程序对它们基于Base 64进行了编码。如果需要参考HTTP协议,可以到
http://www.ietf.org/rfc/rfc2616.txt


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/22331/showart_149706.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP