提问者:小点点

使用apache httpclient作为PoolingHttpClientConnectionManager上泽西客户端的后端


我尝试使用apache httpclient作为jersey客户端的后端来自动处理cookie,这是我的代码

class ClientHelper {
  public static HttpClientConnectionManager customConnectionManager() throws Exception {
  final SSLContext sslContext = SSLContext.getInstance("SSL");

sslContext.init(null, new TrustManager[]{new X509TrustManager() {
  @Override
  public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
      throws CertificateException {
    System.out.println("========checkClientTrusted=========");
  }

  @Override
  public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
      throws CertificateException {
    System.out.println("========checkServerTrusted==========");
  }

  @Override
  public X509Certificate[] getAcceptedIssuers() {
    return null;
  }
}}, new SecureRandom());

SSLConnectionSocketFactory
    sslConnectionSocketFactory =
    new SSLConnectionSocketFactory(sslContext);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
    .register("https", sslConnectionSocketFactory)
    .register("http", PlainConnectionSocketFactory.getSocketFactory())
    .build();
PoolingHttpClientConnectionManager phcc = new PoolingHttpClientConnectionManager(registry);
return phcc;
}

public static Client createClient() {
  HttpClient apacheClient = null;
  try {
  apacheClient =
      HttpClientBuilder.create().setConnectionManager(customConnectionManager()).build();

} catch (Exception e) {
  e.printStackTrace();
}
Client client = new Client(new ApacheHttpClient4Handler(apacheClient,
                                                        new BasicCookieStore(),
                                                        true));
return client;
  }
  }

我尝试使用apache httpclient作为jersey客户端的后端(为了处理cookie)

然后,我创建一个简单的类来测试客户端,

import com.sun.jersey.api.client.Client;
....

public class ApiTest {

  private static Client client;

  public String getAuth(String username, String passwd) {

  Map<String, String> formParams = new HashMap<String, String>();
  formParams.put("username", String.valueOf(username));
  formParams.put("passwd", String.valueOf(passwd));

try {
  String basePath = "https://xyzhost/login";

  if (client == null) {
    client = ClientHelper.createClient();
    client.addFilter(new LoggingFilter(System.out));
  }

  WebResource webResource = client.resource(basePath);

  ClientResponse response = webResource.type("application/x-www-form-urlencoded").accept("application/json")
      .post(ClientResponse.class, processFormParams(formParams));
  if (response != null) {
    String authRes = response.getEntity(String.class);
    response.close();

    return authRes;
  } else {
    return null;
  }
} catch (Exception ex) {
  ex.printStackTrace();
  return null;
}
 }


 public String getSummary(){

try {
  String basePath = "https://xyzhost/summary";

  if (client == null) {
    client = ClientHelper.createClient();
  }

  WebResource webResource = client
      .resource(basePath);

  ClientResponse response = webResource.type("application/x-www-form-urlencoded").accept("application/json")
      .post(ClientResponse.class, processFormParams(formParams));

  if (response != null) {
    String serviceRes = response.getEntity(String.class);
    response.close();
    return serviceRes;
  } else {
    return null;
  }
  } catch (Exception ex) {
    ex.printStackTrace();
    return null;
  }
}

public static void main(String[] args) throws ApiException {
  String username = "testuser";
  String passwd = "testpasswd";
  AuthApi apiTest = new ApiTest();
  String auth =apiTest.getAuth(username, passwd);
  String reslut1 = apiTest.getSummary();
  String result2 = apiTest.getSummary();
  String result3 = apiTest.getSummary();
  String result4 = apiTest.getSummary();
}
}

所以,我使用同一个客户端来命中同一个主机下的服务。我可以成功获得“auth”和“结果1”的响应,但是客户端卡在了下面部分的“结果2”中

  ClientResponse response = webResource.type("application/x-www-form-urlencoded").accept("application/json")
      .post(ClientResponse.class, processFormParams(formParams));

我尝试修改以下部分:

PoolingHttpClientConnectionManager phcc= new PoolingHttpClientConnectionManager(registry);
phcc.setDefaultMaxPerRoute(10);

然后,ApiTest工作,不会卡住。我想连接有一些问题,因为默认情况下,poolingHttpClientConnectionManager的每个路由的最大值是2,所以我的ApiTest会卡在第3个请求中。我认为连接已经释放,因为我已经使用了响应实体,

if (response != null) {
    String serviceRes = response.getEntity(String.class);
    response.close();
    return serviceRes;
  }

但它似乎根本不起作用,连接似乎没有释放。

有人能帮忙吗?谢谢!


共1个答案

匿名用户

我得到一个解决方案:将jersey-client的版本从1.17切换到1.18,然后问题就解决了!

<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-client</artifactId>
  <version>1.18</version>
  <scope>compile</scope>
</dependency>