HttpClient 4.4挂起任何请求

时间:2015-03-29 12:51:17

标签: java apache-httpclient-4.x

我遇到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的日志条目。不确定是否预期。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

此问题是由org.codehaus.mojo:exec-maven-plugin中的一个小问题引起的。

即,当您设置<includePluginDependencies>true</includePluginDependencies>时,您也会获得插件的SLF4J依赖项,并且不能将其排除在我能看到的范围之外。解决这个问题的简单方法是在插件依赖项部分中首先声明您的SLF4J / Logback依赖项。

我发现没有必要再次声明slf4j-api,只是在我的情况下使用logback-classic和jcl-over-slf4j。