|
楼主 |
发表于 2005-4-6 21:02:07
|
显示全部楼层
Post by eTony
How to make your Java applications work across proxies and firewalls?
Introduction
Java provides a rich API for networking and I/O. The initial releases of the JDK did not contain native support for proxies and firewall authentications -- however, as of J2SDK1.4, Java also provides native support for proxies and authentication. In this article, I will cover three mechanisms for making your Java applications proxy-aware -- the first two are high-level, but slightly less powerful methods, and the last one is a slighly lower-level but more powerful method.
Configuring your Java Runtime Environment to use proxies
Irrespective of which method you choose to use, you will have to configure the JRE to use proxies. This is done by setting the following System properties:
// This is for HTTP Proxies
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", "proxy.somedomain.org");
System.getProperties().put("proxyPort", "3128");
// This is for FTP Proxies
defaultProperties.put( "ftpProxySet", "true" );
defaultProperties.put( "ftpProxyHost", "proxy-host-name" );
defaultProperties.put( "ftpProxyPort", "85" );
// This is for SOCKS Proxies
System.getProperties().setProperty("socksProxySet", "true");
System.getProperties().setProperty("socksProxyHost", proxyServerName);
System.getProperties().setProperty("socksProxyPort", proxyServerPort);
Java 2 Native Support
Java 2 has a native authentication framework which can be used to provide authentication for a wide range of services in a platform and protocol independent mechanism. This is done by providing Authenticator objects.
import java.net.*;
import java.io.*;
public class TestProxy{
public static final String CRLF = "\r\n";
public TestProxy(){
try{
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", "proxy.domain.com");
System.getProperties().put("proxyPort", "3128");
Authenticator.setDefault(new MyAuthenticator());
URL url = new URL("http://www.google.com");
URLConnection conn = url.openConnection();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String args[]){
TestProxy tp = new TestProxy();
}
}
class MyAuthenticator extends Authenticator{
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication("username", "password".toCharArray());
}
}
Using URLConnection API
Prior to Java 2, the SDK did not have native support for proxies. So, how does you go about making your old Java code proxy aware? Well, actually its not all that difficult. Basically, you have to play aorund with the HTTP headers yourself.
For an HTTP proxy, all HTTP requests should contain a Proxy-Authorization header ([??]) which stores the user name and password in a Base-64 encoding. You can use any base-64 encoder (and there are many available) -- for this example, I have used the encoder provided by Sun itself. However, it is not part of the standard JDK, so this code is not guaranteed to work. A simple implementation of a Base-64 encoder can be found here [??]
Having encoded the user name and password, you simply need to open a URLConnection, and set the request propert as shown below. Thats it, you're done!
String authString = "username" + ":" + "password";
String auth = "Basic " + new sun.misc.BASE64Encoder().encode(authString.getBytes());
URL url = new URL("http://www.google.com");
URLConnection conn = url.openConnection();
conn.setRequestProperty("roxy-Authorization", auth);
Using raw Socket Headers
The above two methods are nice and convinient, however, they are quite restrictive. For instance, consider the case of HTTP proxies. Both the methods discussed above will work only with the HTTP GET/PUT/POST methods. These work for most conventional web applications. But now suppose that you want to write a Jabber client which works behind firewalls. To do that, you will need a socket object which would work accross the proxy -- because you would like to do arbitrary read/writes to the server.
Many HTTP proxies allow this functionality via the HTTP CONNECT method. Basically, the proxy opens a socket to the server on your behalf and returns a handle of the socket to you. Any further traffic on that socket will be forward AS-IS without any inspection/modification by the proxy. For doing this in Java, you need to supply HTTP headers manually over a raw TCP socket. Here is how to do this:
String authString = "username" + ":" + "password";
String auth = "Basic " + new sun.misc.BASE64Encoder().encode(authString.getBytes());
Socket socket = new Socket("vsnlproxy.iitk.ac.in", 3128);
OutputStream out = socket.getOutputStream();
out.write(("CONNECT toc.oscar.aol.com:9898 HTTP/1.1" + CRLF + "Host: toc.oscar.aol.com:9898" + CRLF).getBytes());
out.write(("roxy-Authorization: " + auth + CRLF).getBytes());
out.write(CRLF.getBytes());
多谢多谢 |
|