使用 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"和"result1"的响应,但客户端在以下部分中卡在"result2"中

  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 将卡在第三个请求中。我认为自从我消耗了响应实体以来,连接已经释放

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

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

任何人都可以帮忙吗?欣赏!

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

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

相关内容

  • 没有找到相关文章

最新更新