在 Java 中抑制运行时控制台警告的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/745022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:59:08  来源:igfitidea点击:

What's the best way to suppress a runtime console warning in Java?

javaconsoleruntimewarningssuppress-warnings

提问by seansand

I am using the getResponseBody() method of the org.apache.commons.httpclient.methods.PostMethod class. However, I am always getting a message written to the console at runtime:

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

WARNING: Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.

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

In the code I have to write the response to a byte array anyway, so it is the getResponseBody() method that I ought to use. But is there an easy way that I can suppress the warning message so I don't have to look at it at every run?

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

If it was a compiler error, I'd use the @SuppressWarningsannotation, but this isn't a compile-time issue; it happens at runtime. Also, I could use getResponseBodyAsStream to write to a ByteArrayOutputStream, but this seems like a hacky way to get around the warning (extra lines of code to do what getResponseBody() is already doing for me).

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

My guess is that the answer involves System.out or System.err manipulation, but is there a good way to do this?

我的猜测是答案涉及 System.out 或 System.err 操作,但是有没有好的方法可以做到这一点?

采纳答案by Randolpho

I would recommend that you do as the warning suggests and use a stream rather than a byte array. If the response you're trying to push is particularly large (suppose it's a large file), you will load it all into memory, and that'd be a very bad thing.

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

You're really better off using streams.

最好使用流。

That said, you might hack around it by replacing System.err or System.out temporarily. They're just PrintStreamobjects, and they're settable with the setOut and setErr methods.

也就是说,您可以通过临时替换 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);

Edit:

编辑:

I agree that it would be preferable to use streams, but as it is now, the target API where I need to put the response is a byte array. If necessary, we can do a refactor to the API that will allow it to take a stream; that would be better. The warning is definitely there for a reason.

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

If you can modify the API, do so. Stream processing is the best way to go in this case. If you can't due to internal pressures or whatever, go @John M's route and pump up the BUFFER_WARN_TRIGGER_LIMIT-- but make sure you have a known contentLength, or even that route will fail.

如果您可以修改 API,请这样做。在这种情况下,流处理是最好的方法。如果由于内部压力或其他原因而无法访问,请转到@John M的路线并提高BUFFER_WARN_TRIGGER_LIMIT- 但请确保您有一个已知的 contentLength ,否则该路线将失败。

回答by mipadi

Assuming the warning is written to stderr, you can always suppress the warning by piping stderr to /dev/null, or whatever the equivalent on your system is.

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

回答by Steve B.

Is the library outputting through log4j? if so, editing the log4j.properties to set the output for this class to "ERROR" would work, e.g.

库是通过 log4j 输出的吗?如果是这样,编辑 log4j.properties 以将此类的输出设置为“ERROR”就可以了,例如

log4j.logger.org.apache.commons.httpclient.methods.PostMethod=ERROR

回答by John M

If you want to cleanly stop this log entry, there's a tunable max that triggers the warning. I saw this looking at the code.

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

        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() looks like the place to set HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT to the desired value.

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

回答by Vineet Reynolds

This issue has already been debated on the ASF JIRA. There are two ways to resolve this:

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

  • Set a higher value for BUFFER_WARN_TRIGGER_LIMIT. A high enough value is more likely to suppress the warning; however, that defeats the purpose of the warning itself. If you are buffering a lot of data to be eventually parsed in one pass, you are better off reading the data from a stream into an array before working on the array.
  • Set the logging level to a higher value for HttpClient, if you are comfortable with ERROR or FATAL.
  • BUFFER_WARN_TRIGGER_LIMIT设置更高的值。足够高的值更有可能抑制警告;然而,这违背了警告本身的目的。如果您正在缓冲大量数据以最终在一次传递中进行解析,则最好在处理数组之前将数据从流中读取到数组中。
  • 如果您对 ERROR 或 FATAL 感到满意,请将 HttpClient 的日志记录级别设置为更高的值。

回答by Mark

to simply 'save' the stderr messages then print them after completion of the main task

简单地“保存” 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);

回答by vivisidea

that warning happends when httpClient have no idea about the length of the return data you should set the content-length attribute in your server end

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

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

after that, that warning should disapear

在那之后,该警告应该消失