【问题标题】:Apache Http EntityUtils.consume() vs EntityUtils.toString()?Apache Http EntityUtils.consume() 与 EntityUtils.toString()?
【发布时间】:2020-07-08 22:26:20
【问题描述】:

我编写了一个 HTTP 客户端,我正在从 REST Web 服务读取数据响应。在阅读了有关 EntityUtils.consume() 和 EntiryUtils.toString() 的多个博客后,我产生了困惑。我想知道以下内容:

  1. 如果 EntityUtils.toString(..) ONLY 就足够了,因为它还会在读取 char 字节后关闭流。或者我也应该做 EntityUtils.consume(..) 作为一个好习惯。

  2. 如果toString() 和consume() 操作都可以使用。如果是,那么应该有什么顺序。

  3. 如果我 EntityUtils.toString() 关闭流;那为什么 EntityUtils.consume(..) 操作中的下一个调用是 entity.isStreaming() 仍然返回 true?

任何人都可以在这里指导我以标准方式使用这些操作。我使用的是 HTTP 版本 4+。

我必须在多线程(网络应用)环境中使用这些配置。

谢谢

【问题讨论】:

    标签: http apache-httpclient-4.x closeablehttpresponse


    【解决方案1】:

    我查看了 apache httpclient commons 网站上的推荐示例。

    在示例中,他们使用了 EntityUtils.toString(..) 而无需在前后使用 EntityUtils.consume(..)。

    他们提到调用 httpclient.close() 确保所有资源都关闭。

    来源:https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientWithResponseHandler.java

    CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpget = new HttpGet("http://httpbin.org/");
    
            System.out.println("Executing request " + httpget.getRequestLine());
    
            // Create a custom response handler
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
    
                @Override
                public String handleResponse(
                        final HttpResponse response) throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return entity != null ? EntityUtils.toString(entity) : null;
                    } else {
                        throw new ClientProtocolException("Unexpected response status: " + status);
                    }
                }
    
            };
            String responseBody = httpclient.execute(httpget, responseHandler);
            System.out.println("----------------------------------------");
            System.out.println(responseBody);
        } finally {
            httpclient.close();
        }
    

    这是上面例子中引用的内容:

    此示例演示如何使用响应处理程序处理 HTTP 响应。这是执行 HTTP 请求和处理 HTTP 响应的推荐方式。这种方法使调用者能够专注于消化 HTTP 响应的过程,并将系统资源释放的任务委托给 HttpClient。使用 HTTP 响应处理程序可确保在所有情况下,底层 HTTP 连接都会自动释放回连接管理器。

    【讨论】:

    • httpClient.close() 将是 Web 应用程序中要做的最后一件事,您可能有多个请求访问同一个 httpClient 以进行远程调用。但是传输方法 httpget.close() 怎么样?如果使用它是一个好习惯?如果我使用它,那会影响性能吗?(可能是几毫秒)
    • 我不确定这是否是最好的方法,但我确实为每个请求构建并关闭了 httpclient,并且性能对我来说是可以接受的(不到 1 秒)。但是我确实有一个 httpclient 的共享连接池,它只在应用程序启动时创建: final CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(poolingHttpClientConnectionManager) .setConnectionManagerShared(true) .setDefaultRequestConfig(defaultRequestConfig).build();
    • httpClinet 在服务器启动时创建。但是有没有办法在服务器启动时也可以打开连接?现在连接会在第一次请求时打开,并且需要花费大量时间来建立路由。
    • 如果使用连接池,那么由于连接会被复用,后续请求会更快。如果您担心第一次请求的时间 - 为什么不在服务器启动时发出第一个请求?
    • 即使我在服务器启动时第一次请求,同样的问题会在空闲连接超时后再次出现,然后下一个请求将再次需要时间。
    猜你喜欢
    • 2021-08-22
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 2012-04-17
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多