我遇到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://stackoverflow.com/");
request.setConfig(requestConfig);
HttpResponse response = httpClient.execute(request);
以下java.net.URL
解决方案没有问题:
URL url = new URL("http://stackoverflow.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
的日志条目。不确定是否预期。
非常感谢任何帮助!
答案 0 :(得分:0)
此问题是由org.codehaus.mojo:exec-maven-plugin
中的一个小问题引起的。
即,当您设置<includePluginDependencies>true</includePluginDependencies>
时,您也会获得插件的SLF4J依赖项,并且不能将其排除在我能看到的范围之外。解决这个问题的简单方法是在插件依赖项部分中首先声明您的SLF4J / Logback依赖项。
我发现没有必要再次声明slf4j-api,只是在我的情况下使用logback-classic和jcl-over-slf4j。