如何在Apache HttpComponents中使用自定义socketfactory

时间:2011-11-22 13:27:22

标签: java apache-httpclient-4.x apache-httpcomponents socketfactory

我一直在尝试在Apache HTTPComponents项目的httpclient库中使用自定义SocketFactory。到目前为止没有运气。我原以为我可以为HttpClient实例设置套接字工厂,但显然不是那么容易。

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html的HttpComponents文档确实提到了套接字工厂,但没有说明如何使用它们。

有人知道这是怎么做的吗?

2 个答案:

答案 0 :(得分:2)

我们使用自定义套接字工厂允许HttpClient连接使用不受信任的证书连接到HTTPS URL。

以下是我们的做法:

  1. 我们从Oleg引用的示例源目录中调整了'EasySSLProtocolSocketFactory'和'EasyX509TrustManager'类的实现。

  2. 在我们的HttpClient启动代码中,我们执行以下操作来启用新的套接字工厂:

    HttpClient httpClient = new HttpClient();
    Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
    Protocol.registerProtocol("https", easyhttps);
    
  3. 因此,只要我们请求https:// URL,就会使用此套接字工厂。

答案 1 :(得分:2)

oleg的答案当然是正确的,我只是想直接把信息放在这里,以防链接变坏。在创建HttpClient的代码中,我使用此代码让它使用我的套接字工厂:

    CustomSocketFactory socketFactory = new CustomSocketFactory();
    Scheme scheme = new Scheme("http", 80, socketFactory);
    httpclient.getConnectionManager().getSchemeRegistry().register(scheme);

CustomSocketFactory是我自己的套接字工厂,我想将它用于普通的HTTP流量,这就是我使用"http"80作为参数的原因。

我的CustomSchemeSocketFactory看起来与此类似:

public class CustomSchemeSocketFactory implements SchemeSocketFactory {

  @Override
  public Socket connectSocket( Socket socket, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpParams params ) throws IOException, UnknownHostException, ConnectTimeoutException {

    if (localAddress != null) {
      socket.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
      socket.bind(localAddress);
    }
    int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
    int soTimeout = HttpConnectionParams.getSoTimeout(params);

    try {
        socket.setSoTimeout(soTimeout);
        socket.connect(remoteAddress, connTimeout );
    } catch (SocketTimeoutException ex) {
        throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
    }

    return socket;
  }

  @Override
  public Socket createSocket( HttpParams params ) throws IOException {
    // create my own socket and return it
  }

  @Override
  public boolean isSecure( Socket socket ) throws IllegalArgumentException {
    return false;
  }

}