簡體   English   中英

如何在不使用HttpEntity的情況下閱讀它?

[英]How do I read HttpEntity without consuming it?

我有org.apache.http.HttpResponse對象,該對象在代碼的不同位置使用。 這些地方之一是日志記錄。

問題是當我運行以下日志代碼時:

HttpEntity entity = response.getEntity();
try {
    String content = Base64.encodeToString(
            EntityUtils.toByteArray(entity), Base64.DEFAULT);
    sb.append(content + "\r\n");
} catch (Exception e) {
    sb.append("\r\n\r\n====EXCEPTION=====\r\n" + e.toString()
            + "\r\n");
}

然后,我嘗試讀取實際處理代碼中的條目內容,這導致代碼引發以下異常:

java.lang.IllegalStateException: Content has been consumed

我的問題是:如何讀取實體而不在日志代碼中使用它?

UPDATE這是我用來將httpresponse轉換為字符串的函數的完整代碼:

static String toString(org.apache.http.HttpResponse response) {
    try {
        if (response == null) {
            return "null";
        }

        StringBuilder sb = new StringBuilder();
        sb.append("==============BEGIN HttpResponse================\r\n");
        StatusLine sl = response.getStatusLine();
        if (sl == null) {
            sb.append("status line is null\r\n");
        } else {
            sb.append(String.format("%s %s\r\n", sl.getStatusCode(),
                    sl.getReasonPhrase()));
        }

        for (Header h : response.getAllHeaders()) {
            if (h == null) {
                sb.append("header is null\r\n");
                continue;
            }
            sb.append(String.format("%s: %s\r\n", h.getName(), h.getValue()));
        }

        sb.append("\r\r\r\n");

        HttpEntity entity = response.getEntity();
        if (entity == null) {
            sb.append("content is null");
        } else {
            try {
                String content = Base64.encodeToString(
                        EntityUtils.toByteArray(entity), Base64.DEFAULT);

                sb.append(content + "\r\n");
            } catch (Exception e) {
                sb.append("\r\n\r\n====EXCEPTION=====\r\n" + e.toString()
                        + "\r\n");
            }
        }

        sb.append("\r\n==============END HttpResponse================\r\n");

        return sb.toString();
    } catch (Exception e) {
        return e.toString();
    }
}

好。 因此,我最終要做的是實現自己的HttpEntity類,而不僅僅是使用response.setEntity(...)替換先前的實體。 該類將結果存儲為二進制數組,並根據需要返回多次。

它可能會給您帶來一些性能問題,但是會起作用:帶記錄功能的HttpClient示例。

private CloseableHttpResponse invoke(HttpRequestBase http) {
        try {
            CloseableHttpResponse response = client.execute(http);
            if (http instanceof HttpPost) {
                InputStream inputStream = ((HttpPost) http).getEntity().getContent();
                String body = IOUtils.toString(inputStream, Charset.defaultCharset());

                HttpEntity respBody = response.getEntity();
                String responseBody = StreamUtils.copyToString(respBody.getContent(), Charset.defaultCharset());
                response.setEntity(new StringEntity(responseBody));
                LOG.info(String.format("Sending request: [%s] %s => [%s] \nPayload:\n%s \nResponse:\n%s", http.getMethod(), http.getURI(), response.getStatusLine(), body, responseBody));
            } else {
                LOG.info(String.format("Sending request: [%s] %s => [%s]", http.getMethod(), http.getURI(), response.getStatusLine()));
            }
            return response;
        } catch (IOException e) {
            throw new RuntimeException("HTTP request failed: " + http.toString(), e);
        }
    }

主要思想如下:
1.撥打http
2.復制到您的響應正文中:

 HttpEntity respBody = response.getEntity();  
 String responseBody = StreamUtils.copyToString(respBody.getContent(), Charset.defaultCharset());
  1. 記錄下來
  2. 設置新的響應實體,如response.setEntity(new StringEntity(responseBody));

該示例適用於小型測試框架,不確定適用於生產應用程序的代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM