我正在通过点击http和https链接的混合来测试HttpClient 4.2。
HttpClient似乎坚持第一次调用的协议。如果第一个呼叫是http,则所有后续的https呼叫都会失败,但http呼叫很好。反之亦然。
这是我使用的测试代码。
@Test
public void testNoRedirectMixed() throws ClientProtocolException, IOException {
HttpClient httpclient = new DefaultHttpClient();
httpclient=WebClientDevWrapper.wrapClient(httpclient);
HttpClientParams.setRedirecting(httpclient.getParams(), false);
{
HttpGet httpget = new HttpGet("http://www.hotmail.com");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
assertTrue(EntityUtils.toString(entity).indexOf("com")>0);
}
try {
HttpGet httpget = new HttpGet("https://www.hotmail.com");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
}catch (Exception e) {
e.printStackTrace();
}
{
HttpGet httpget = new HttpGet("http://www.baidu.com");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
assertTrue(EntityUtils.toString(entity).indexOf("com")>0);
}
}
第二个请求(https)将失败,但百度请求没问题。
引起:org.apache.http.HttpException:无法建立路由:planned = {s} - > https://www.hotmail.com; current = {s} - > http://www.hotmail.com 在org.apache.http.impl.client.DefaultRequestDirector.establishRoute(DefaultRequestDirector.java:842)
我还必须禁用重定向,因为Hotmail会重定向请求:http://www.hotmail.com - > https://www.hotmail.com或https://www.hotmail.com - > https://www.live.com。在任何一种情况下都会抛出类似的错误。
包装器如下所示。它用于接受所有证书。
public class WebClientDevWrapper {
public static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", ssf, 443));
DefaultHttpClient client= new DefaultHttpClient(ccm, base.getParams());
return client;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
}
答案 0 :(得分:3)
HttpClient应该能够绝对透明地管理用户的连接。此问题可能是由4.2版本(see HTTPCLIENT-1193)中引入的回归引起的。
在发布4.2.1版本之前,使用PoolingConnectionManager或SingleConnectionManager而不是默认值。
答案 1 :(得分:0)
您正尝试使用一个连接与多个不同的站点进行通信。 AFAIR您必须为每个唯一网站创建新连接(==新客户)。