HttpClient 4.4 挂起任何请求
HttpClient 4.4 hangs on any request
我遇到 Apache HttpClieint 4.4 在任何请求上挂起的问题,即使基于 java.net.URL
的简单解决方案可以很好地检索相同的资源。
给定以下 HttpClient 配置:
RequestConfig requestConfig = RequestConfig.custom()
.setExpectContinueEnabled(false)
.setCookieSpec(CookieSpecs.DEFAULT)
.setRedirectsEnabled(false)
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setStaleConnectionCheckEnabled(true)
.build();
RegistryBuilder<ConnectionSocketFactory> connRegistryBuilder = RegistryBuilder.create();
connRegistryBuilder.register("http", PlainConnectionSocketFactory.INSTANCE);
try { // Fixing: https://code.google.com/p/crawler4j/issues/detail?id=174
// By always trusting the ssl certificate
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(final X509Certificate[] chain, String authType) {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
connRegistryBuilder.register("https", sslsf);
} catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) {
LOGGER.warn("Exception thrown while trying to register https");
LOGGER.debug("Stacktrace", e);
}
Registry<ConnectionSocketFactory> connRegistry = connRegistryBuilder.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(connRegistry);
connectionManager.setMaxTotal(5);
connectionManager.setDefaultMaxPerRoute(5);
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.setDefaultRequestConfig(requestConfig);
clientBuilder.setConnectionManager(connectionManager);
clientBuilder.setUserAgent("Cognitio");
HttpClient httpClient = clientBuilder.build();
下面的 HttpClient 请求挂起有什么充分的理由吗?
HttpGet request = new HttpGet("http://whosebug.com/");
request.setConfig(requestConfig);
HttpResponse response = httpClient.execute(request);
以下 java.net.URL
解决方案没有问题:
URL url = new URL("http://whosebug.com");
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
当我用日志语句轰炸我的应用程序时,我确定它挂在 httpClient.execute
部分,尽管指定了超时,但未能超时。此外,我将 SLF4J 与 JCL 桥一起使用,但是当我将其设置为调试时,我没有收到 org.apache.http
的日志条目。不确定这是否符合预期。
非常感谢任何帮助!
此问题是由 org.codehaus.mojo:exec-maven-plugin
中的一个小问题引起的。
也就是说,当你设置 <includePluginDependencies>true</includePluginDependencies>
时,你也会得到插件的 SLF4J 依赖项,并且它们不能被排除在我所看到的之外。解决这个问题的简单方法是首先在插件依赖项部分声明 SLF4J/Logback 依赖项。
我发现不需要再次声明 slf4j-api,在我的例子中只需声明 logback-classic 和 jcl-over-slf4j。
我遇到 Apache HttpClieint 4.4 在任何请求上挂起的问题,即使基于 java.net.URL
的简单解决方案可以很好地检索相同的资源。
给定以下 HttpClient 配置:
RequestConfig requestConfig = RequestConfig.custom()
.setExpectContinueEnabled(false)
.setCookieSpec(CookieSpecs.DEFAULT)
.setRedirectsEnabled(false)
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setStaleConnectionCheckEnabled(true)
.build();
RegistryBuilder<ConnectionSocketFactory> connRegistryBuilder = RegistryBuilder.create();
connRegistryBuilder.register("http", PlainConnectionSocketFactory.INSTANCE);
try { // Fixing: https://code.google.com/p/crawler4j/issues/detail?id=174
// By always trusting the ssl certificate
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(final X509Certificate[] chain, String authType) {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
connRegistryBuilder.register("https", sslsf);
} catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) {
LOGGER.warn("Exception thrown while trying to register https");
LOGGER.debug("Stacktrace", e);
}
Registry<ConnectionSocketFactory> connRegistry = connRegistryBuilder.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(connRegistry);
connectionManager.setMaxTotal(5);
connectionManager.setDefaultMaxPerRoute(5);
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.setDefaultRequestConfig(requestConfig);
clientBuilder.setConnectionManager(connectionManager);
clientBuilder.setUserAgent("Cognitio");
HttpClient httpClient = clientBuilder.build();
下面的 HttpClient 请求挂起有什么充分的理由吗?
HttpGet request = new HttpGet("http://whosebug.com/");
request.setConfig(requestConfig);
HttpResponse response = httpClient.execute(request);
以下 java.net.URL
解决方案没有问题:
URL url = new URL("http://whosebug.com");
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
当我用日志语句轰炸我的应用程序时,我确定它挂在 httpClient.execute
部分,尽管指定了超时,但未能超时。此外,我将 SLF4J 与 JCL 桥一起使用,但是当我将其设置为调试时,我没有收到 org.apache.http
的日志条目。不确定这是否符合预期。
非常感谢任何帮助!
此问题是由 org.codehaus.mojo:exec-maven-plugin
中的一个小问题引起的。
也就是说,当你设置 <includePluginDependencies>true</includePluginDependencies>
时,你也会得到插件的 SLF4J 依赖项,并且它们不能被排除在我所看到的之外。解决这个问题的简单方法是首先在插件依赖项部分声明 SLF4J/Logback 依赖项。
我发现不需要再次声明 slf4j-api,在我的例子中只需声明 logback-classic 和 jcl-over-slf4j。