我尝试使用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>