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 閱讀(2918) 評論(0)  編輯  收藏 所屬分類: java

          My Links

          Blog Stats

          常用鏈接

          留言簿(9)

          隨筆分類(94)

          隨筆檔案(93)

          tech

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 江西省| 仁怀市| 邢台市| 龙里县| 遂平县| 海伦市| 项城市| 葫芦岛市| 姚安县| 芷江| 饶河县| 怀宁县| 内江市| 大英县| 靖州| 尚义县| 云林县| 中卫市| 兴业县| 江阴市| 灵石县| 仲巴县| 望江县| 红桥区| 陆河县| 汝州市| 阜平县| 麻城市| 延津县| 武定县| 鲁山县| 得荣县| 中超| 蛟河市| 界首市| 新化县| 忻城县| 韩城市| 旬阳县| 琼结县| 虎林市|