Java HttpClient 似乎在缓存内容

标签 java multithreading http httpclient apache-httpcomponents

我正在构建一个简单的网络抓取工具,我需要获取同一个页面几百次,并且页面中有一个动态属性,应该在每次请求时更改。我已经构建了一个基于多线程 HttpClient 的类来处理请求,并且我正在使用 ExecutorService 创建线程池并运行线程。问题是动态属性有时不会在每个请求上改变,我最终在 3 或 4 个后续线程上获得相同的值。我已经阅读了很多关于 HttpClient 的文章,但我真的找不到这个问题的根源。可能是关于缓存的东西,或者类似的东西!?

更新:这是在每个线程中执行的代码:

HttpContext localContext = new BasicHttpContext();

HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params,
        HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);

ClientConnectionManager connman = new ThreadSafeClientConnManager();

DefaultHttpClient httpclient = new DefaultHttpClient(connman, params);

HttpHost proxy = new HttpHost(inc_proxy, Integer.valueOf(inc_port));
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
        proxy);

HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent",
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");

String iden = null;
int timeoutConnection = 10000;
HttpConnectionParams.setConnectionTimeout(httpGet.getParams(),
        timeoutConnection);

try {

    HttpResponse response = httpclient.execute(httpGet, localContext);

    HttpEntity entity = response.getEntity();

    if (entity != null) {

        InputStream instream = entity.getContent();
        String result = convertStreamToString(instream);
        // System.out.printf("Resultado\n %s",result +"\n");
        instream.close();

        iden = StringUtils
                .substringBetween(result,
                        "<input name=\"iden\" value=\"",
                        "\" type=\"hidden\"/>");
        System.out.printf("IDEN:%s\n", iden);
        EntityUtils.consume(entity);
    }

}

catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    System.out.println("Excepção CP");

} catch (IOException e) {
    // TODO Auto-generated catch block
    System.out.println("Excepção IO");
}

最佳答案

HTTPClient 默认不使用缓存(仅当您使用 DefaultHttpClient 类时)。它会这样做,如果你使用 CachingHttpClient这是HttpClient启用缓存的界面装饰器:

HttpClient client = new CachingHttpClient(new DefaultHttpClient(), cacheConfiguration);

然后,它分析If-Modified-SinceIf-None-Match header 以确定是否执行对远程服务器的请求,或者是否从缓存中返回其结果。

我怀疑您的问题是由位于您的应用程序和远程服务器之间的代理服务器引起的。

您可以使用 curl 轻松测试它应用;执行一些省略代理的请求:

#!/bin/bash

for i in {1..50}
do
  echo "*** Performing request number $i"
  curl -D - http://yourserveraddress.com -o $i -s
done

然后,执行diff在所有下载的文件之间。他们都应该有你提到的差异。然后,添加 -x/--proxy <host[:port]> curl 选项,执行此脚本并再次比较文件。如果某些响应与其他响应相同,那么您可以确定这是代理服务器问题。

关于Java HttpClient 似乎在缓存内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9641679/

相关文章:

java - 如何更改 Java 中派生类的成员函数的签名

java - 在数据库中排序数据的优缺点?

android - Qt 网络服务器与移动浏览器

http - Clarifai API 和 cURL?

java - 了解 Spring 的身份验证对象及其创建的上下文

java - Files.readAllBytes() 读取文件后是否关闭输入流?

java - Java 7 fork/join 是否保证在单独的 CPU 中执行线程

python - Python中是否有分布式任务队列使我能够杀死不愿合作的挂起任务

java - 执行器停止所有正在运行的任务并重新运行

http - 使用 HTTP/2 时可以有多个开放的 SSE channel 吗?