17

我正在使用 org.apache.commons.httpclient.methods.PostMethod 类的 getResponseBody() 方法。但是,我总是在运行时收到一条写入控制台的消息:

警告:要缓冲大或未知大小的响应主体。建议改用 getResponseBodyAsStream。

在代码中,无论如何我都必须将响应写入字节数组,所以我应该使用 getResponseBody() 方法。但是有没有一种简单的方法可以抑制警告消息,这样我就不必在每次运行时都查看它?

如果是编译器错误,我会使用@SuppressWarnings注释,但这不是编译时问题;它发生在运行时。此外,我可以使用 getResponseBodyAsStream 写入 ByteArrayOutputStream,但这似乎是一种绕过警告的 hacky 方法(额外的代码行来完成 getResponseBody() 已经为我做的事情)。

我的猜测是答案涉及 System.out 或 System.err 操作,但有没有好的方法呢?

4

7 回答 7

19

如果您想彻底停止此日志条目,则有一个可调整的最大值来触发警告。我在看代码时看到了这个。

        int limit = getParams().getIntParameter(HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT, 1024*1024);
        if ((contentLength == -1) || (contentLength > limit)) {
            LOG.warn("Going to buffer response body of large or unknown size. "
                    +"Using getResponseBodyAsStream instead is recommended.");
        }

HttpMethodBase.setParams() 看起来像是将 HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT 设置为所需值的地方。

于 2009-04-13T19:23:56.940 回答
12

当 httpClient 不知道返回数据的长度时会发生该警告,您应该在服务器端设置 content-length 属性

response.addHeader("Content-Type", "text/html; charset=utf-8");
response.addHeader("Content-Length", String.valueOf(output.getBytes("utf8").length));

之后,该警告应该消失

于 2011-07-22T05:30:28.167 回答
11

我建议您按照警告的建议进行操作,并使用流而不是字节数组。如果您尝试推送的响应特别大(假设它是一个大文件),您会将其全部加载到内存中,那将是一件非常糟糕的事情。

使用流真的会更好。

也就是说,您可以通过临时替换 System.err 或 System.out 来绕过它。它们只是PrintStream对象,可以使用 setOut 和 setErr 方法设置。

PrintStream oldErr = System.err;
PrintStream newErr = new PrintStream(new ByteArrayOutputStream());
System.setErr(newErr);

// do your work

System.setErr(oldErr);

编辑:

我同意最好使用流,但就像现在一样,我需要放置响应的目标 API 是一个字节数组。如有必要,我们可以对 API 进行重构,使其能够获取流;那会更好。警告肯定是有原因的。

如果您可以修改 API,请执行此操作。在这种情况下,流处理是最好的方法。如果由于内部压力或其他原因您不能,请转到@John M的路线并提高BUFFER_WARN_TRIGGER_LIMIT-- 但请确保您有已知的 contentLength,否则即使该路线也会失败。

于 2009-04-13T19:31:41.537 回答
8

库是通过 log4j 输出的吗?如果是这样,编辑 log4j.properties 以将此类的输出设置为“错误”将起作用,例如

log4j.logger.org.apache.commons.httpclient.methods.PostMethod=ERROR
于 2009-04-13T19:21:25.057 回答
4

这个问题已经在 ASF JIRA 上进行了辩论。有两种方法可以解决这个问题:

  • 为BUFFER_WARN_TRIGGER_LIMIT设置更高的值。足够高的值更有可能抑制警告;但是,这违背了警告本身的目的。如果您要缓冲大量数据以最终一次性解析,那么最好在处理数组之前将数据从流中读取到数组中。
  • 如果您对 ERROR 或 FATAL 感到满意,请将 HttpClient 的日志记录级别设置为更高的值。
于 2009-04-13T22:51:22.167 回答
1

假设将警告写入 stderr,您始终可以通过将 stderr 管道传输到/dev/null或系统上的任何等效项来抑制警告。

于 2009-04-13T19:16:00.313 回答
1

简单地“保存”stderr 消息,然后在完成主要任务后打印它们

PrintStream origErr = System.err;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream newErr = new PrintStream(baos);
System.setErr(newErr);

====== do stuff ======

System.setErr(origErr);
System.err.print(baos);
于 2011-07-03T20:09:36.757 回答