Java 禁用Tomcat中所有默认的HTTP错误响应内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/794329/
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 19:34:39  来源:igfitidea点击:

Disable all default HTTP error response content in Tomcat

javahttptomcatservletshttpresponse

提问by Rob Hruska

By default, Tomcat sends some HTML content back to the client if it encounters something like an HTTP 404. I know that via web.xmlan <error-page>can be configuredto customize this content.

默认情况下,Tomcat的发送一些HTML内容返回给客户端,如果它通过遇到类似的HTTP 404。我知道,web.xml一个<error-page>可以配置自定义此内容。

However, I'd just like for Tomcat to not send anythingin terms of response content (I'd still like the status code, of course). Is there any way to easily configure this?

但是,我只是希望 Tomcat在响应内容方面不发送任何内容(当然,我仍然喜欢状态代码)。有什么方法可以轻松配置它吗?

I'm trying to avoid A) explicitly sending empty content on the response stream from my Servlet, and B) configuring custom error pages for a whole bunch of HTTP error statuses in my web.xml.

我试图避免 A) 在我的 Servlet 的响应流上显式发送空内容,以及 B) 在我的web.xml.

For some background, I'm developing an HTTP API and am controlling my own response content. So for an HTTP 500, for example, I'm populating some XML content on the response containing error information. For situations like an HTTP 404, the HTTP response status is sufficient for clients, and the content tomcat is sending is unnecessary. If there's a different approach, I'm open to hearing it.

对于某些背景,我正在开发一个 HTTP API 并控制我自己的响应内容。例如,对于 HTTP 500,我在包含错误信息的响应中填充一些 XML 内容。对于像 HTTP 404 这样的情况,客户端的 HTTP 响应状态就足够了,而 tomcat 正在发送的内容是不必要的。如果有不同的方法,我愿意倾听。

Edit:After continued investigation, I still can't find much in the way of a solution. If someone can definitively say this is not possible, or provide a resource with evidence that it will not work, I'll accept that as an answer and try and work around it.

编辑:经过继续调查,我仍然找不到解决办法。如果有人可以明确地说这是不可能的,或者提供资源证明它不起作用,我会接受它作为答案并尝试解决它。

采纳答案by matt b

If you do not want tomcat to show an error page, then do not use sendError(...). Instead use setStatus(...).

如果您不希望 tomcat 显示错误页面,则不要使用 sendError(...)。而是使用 setStatus(...)。

e.g. if you want to give a 405 response, then you do

例如,如果您想给出 405 响应,那么您可以

response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);      
response.getWriter().println("The method " + request.getMethod() + 
   " is not supported by this service.");

Also remember not to throw any Exceptions from your servlet. Instead catch the Exception and, again, set the statusCode your self.

还要记住不要从您的 servlet 中抛出任何异常。而是捕获异常,并再次将 statusCode 设置为您自己。

i.e.

IE

protected void service(HttpServletRequest request,
      HttpServletResponse response) throws IOException {
  try {

    // servlet code here, e.g. super.service(request, response);

  } catch (Exception e) {
    // log the error with a timestamp, show the timestamp to the user
    long now = System.currentTimeMillis();
    log("Exception " + now, e);
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    response.getWriter().println("Guru meditation: " + now);
  }
}

of course, if you do not want any content, then just don't write anything to the writer, just set the status.

当然,如果你不想要任何内容​​,那么就不要向作者写任何内容,只需设置状态即可。

回答by matt b

Why not just configure the <error-page>element with an empty HTML page?

为什么不直接<error-page>用一个空的 HTML 页面来配置元素呢?

回答by manikanta

As Heikki said, setting the status instead of sendError()causes the Tomcat not touch the response entity/body/payload.

正如 Heikki 所说,设置状态而不是sendError()导致 Tomcat 不接触响应实体/主体/有效负载。

If you only want to send the response headers without any entity, like in my case,

如果您只想发送没有任何实体的响应标头,例如我的情况,

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentLength(0);

does the trick. With Content-Length: 0, the print()will have no effect even if used, like:

诀窍。使用Content-Length: 0print()即使使用也没有效果,例如:

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentLength(0);
response.getWriter().print("this string will be ignored due to the above line");

the client receives something like:

客户端收到类似的东西:

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 0
Date: Wed, 28 Sep 2011 08:59:49 GMT

If you want to send some error message, use the setContentLength()with message length (other than zero) or you can leave it to the server

如果你想发送一些错误消息,使用setContentLength()消息长度(非零)或者你可以把它留给服务器

回答by Clive Evans

The quick, slightly dirty, but easy way of stopping Tomcat from sending any error body is to call setErrorReportValveClass against the tomcat host, with a custom error report valve which overrides report to do nothing. ie:

阻止 Tomcat 发送任何错误正文的快速、稍微脏一点但简单的方法是针对 tomcat 主机调用 setErrorReportValveClass,并使用自定义错误报告阀覆盖 report 以使其不执行任何操作。IE:

public class SecureErrorReportValve extends ErrorReportValve {

@Override
protected void report(Request request,Response response,Throwable throwable) {
}

}

and set it with:

并将其设置为:

  ((StandardHost) tomcat.getHost()).setErrorReportValveClass(yourErrorValveClassName);

If you want to send your message, and just think Tomcat shouldn't mess with it, you want something along the lines of:

如果您想发送您的消息,并且只是认为 Tomcat 不应该弄乱它,那么您需要以下内容:

@Override
protected void report(final Request request, final Response response, final Throwable throwable) {
    String message = response.getMessage();
    if (message != null) {
        try {
            response.getWriter().print(message);
            response.finishResponse();
        } catch (IOException e) {
        }
    }
}

回答by Michael-O

Though this question is a bit old, I ran into this problem too. First of all, Tomcat's behavior is absolutely correct. This is per Servlet Spec. One should not alter Tomcat's behavior against the spec. As Heikki Vesalainen and mrCoder mentioned, use setStatusand setStatusonly.

虽然这个问题有点老,但我也遇到了这个问题。首先,Tomcat的行为是绝对正确的。这是每个 Servlet 规范。不应根据规范更改 Tomcat 的行为。正如 Heikki Vesalainen 和 mrCoder 所提到的,使用setStatusand setStatusonly。

To whom it may concern, I have raised a ticketwith Tomcat to improve the docs of sendError.

要敬启者,我都提出了使用Tomcat改善的文档sendError

回答by Erich Eichinger

Although it's Servlet spec compliant, for security reasons I don't want tomcat or any other Servlet container to send error details. I struggled with this as well a bit. After searching and trying, the solution can be summed up as:

尽管它符合 Servlet 规范,但出于安全原因,我不希望 tomcat 或任何其他 Servlet 容器发送错误详细信息。我也有点挣扎。经过搜索和尝试,解决方案可以总结为:

  1. as others mentioned, don't use sendError(), use setStatus()instead
  2. frameworks like e.g. Spring Security use sendError()though...
  3. write a Filterthat
    a. redirects calls to sendError()to setStatus()
    b. flushes the response at the end to prevent the container from further modifying the response
  1. 正如其他人提到的,不要使用sendError()setStatus()而是 使用
  2. 框架,例如 Spring Security 使用sendError()虽然......
  3. 写一个Filter那个
    。将呼叫重定向sendError()setStatus()
    b。最后刷新响应以防止容器进一步修改响应

A little example servlet filter doing this can be found here.

可以在此处找到执行此操作的小示例 servlet 过滤器

回答by reallynice

Although this doesn't respond exactly to the "not send anything" statement on the question, and on the wave of Clive Evans' answer, I found out that in tomcat you can make those too much verbose texts go away from error pages without creating a custom ErrorReportValve.

虽然这并没有完全回应关于这个问题的“不发送任何东西”的声明,并且在克莱夫埃文斯的回答浪潮中,我发现在 tomcat 中你可以让那些太多冗长的文本从错误页面中消失而不创建自定义 ErrorReportValve。

You can accomplish to this customizing ErrorReportValve through the 2 params "showReport" and "showServerInfo" on your "server.xml":

您可以通过“server.xml”上的 2 个参数“showReport”和“showServerInfo”来完成此自定义 ErrorReportValve:

<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" />

Link to official documentation.

官方文档链接

Worked for me on tomcat 7.0.55, didn't work for me on tomcat 7.0.47 (I think because of something reported on the following link http://www.mail-archive.com/[email protected]/msg113856.html)

在 tomcat 7.0.55 上为我工作,在 tomcat 7.0.47 上对我不起作用(我认为是因为以下链接中报告的内容http://www.mail-archive.com/[email protected] /msg113856.html)

回答by Jossef Harush

Configure <error-page>Elements in web.xml

配置<error-page>元素web.xml

Edit $CATALINA_HOME/conf/web.xml, add at the end the following <error-page>, save and restart tomcat

编辑$CATALINA_HOME/conf/web.xml,在最后添加以下内容<error-page>,保存并重启tomcat

<web-app>

...
...
...

    <error-page>
        <error-code>404</error-code>
        <location>/404.html</location>
    </error-page>

    <error-page>
        <error-code>500</error-code>
        <location>/500.html</location>
    </error-page>

    <error-page>
        <error-code>400</error-code>
        <location>/400.html</location>
    </error-page>

</web-app>
  • It works great as I expect even though I didn't actually created a valid routes for those specified locationvalues (e.g. /400.html)
  • 即使我实际上并没有为那些指定的location值创建有效的路由(例如/400.html


before

enter image description here

在此处输入图片说明

after

enter image description here

在此处输入图片说明