stone2083

httpclient ssl support

手头上一些工作,需要经常访问公司内网的数据,为了减少重复的劳动力,就考虑程序帮忙爬取信息数据。
apache下httpclient是一个很好的工具,不过公司内网是使用HTTPS协议的,于是乎,就需要考虑如何让httpclient支持https。
支持ssl的关键,在于如何创建一个SSLSocket,幸好,httpclient提供了支持。

请看:
org.apache.commons.httpclient.protocol.ProtocolSocketFactory
javadocs:A factory for creating Sockets.

实现一个简单的EasySSLProtocolSocketFactory,详见代码:
public class EasySSLProtocolSocketFactory implements ProtocolSocketFactory {

    
private SSLContext sslcontext = null;

    
private String     ksfile;
    
private String     tksfile;
    
private String     kspwd;
    
private String     tkspwd;

    
public EasySSLProtocolSocketFactory(String ks, String kspwd, String tks, String tkspwd){
        
this.ksfile = ks;
        
this.kspwd = kspwd;
        
this.tksfile = tks;
        
this.tkspwd = tkspwd;
    }

    
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException,
                                                                                             UnknownHostException {
        
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
    }

    
public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort,
                               
final HttpConnectionParams params) throws IOException, UnknownHostException,
                                                                 ConnectTimeoutException {
        
if (params == null) {
            
throw new IllegalArgumentException("Parameters may not be null");
        }
        
int timeout = params.getConnectionTimeout();
        SocketFactory socketfactory 
= getSSLContext().getSocketFactory();
        
if (timeout == 0) {
            
return socketfactory.createSocket(host, port, localAddress, localPort);
        } 
else {
            Socket socket 
= socketfactory.createSocket();
            SocketAddress localaddr 
= new InetSocketAddress(localAddress, localPort);
            SocketAddress remoteaddr 
= new InetSocketAddress(host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
            
return socket;
        }
    }

    
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        
return getSSLContext().getSocketFactory().createSocket(host, port);
    }

    
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
                                                                                       UnknownHostException {
        
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    
private SSLContext createEasySSLContext() {
        
try {
            SSLContext context 
= SSLContext.getInstance("SSL");

            KeyManagerFactory kmf 
= KeyManagerFactory.getInstance("SunX509");
            TrustManagerFactory tmf 
= TrustManagerFactory.getInstance("SunX509");

            KeyStore ks 
= KeyStore.getInstance("JKS");
            KeyStore tks 
= KeyStore.getInstance("JKS");

            ks.load(
new FileInputStream(ksfile), kspwd.toCharArray());
            tks.load(
new FileInputStream(tksfile), tkspwd.toCharArray());

            kmf.init(ks, kspwd.toCharArray());
            tmf.init(tks);

            context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), 
null);
            
return context;
        } 
catch (Exception e) {
            
throw new HttpClientError(e.toString());
        }
    }

    
private SSLContext getSSLContext() {
        
if (this.sslcontext == null) {
            
this.sslcontext = createEasySSLContext();
        }
        
return this.sslcontext;
    }

}

备注:
至于ssl相关的知识,和如何创建java key store,可见:
SSL双向认证java实现


如何使用,也简单:
Protocol.registerProtocol("https", new Protocol("https", new EasySSLProtocolSocketFactory(KS_FILE, KS_PWD, TKS_FILE, TKS_PWD), 443))

官方资料:
http://hc.apache.org/httpclient-3.x/sslguide.html

演示代码:
httpclient-ssl.zip

posted on 2010-01-30 14:39 stone2083 阅读(2901) 评论(0)  编辑  收藏 所属分类: java


只有注册用户登录后才能发表评论。


网站导航: