httpclient ssl support

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

你可能感兴趣的:(httpclient ssl support)