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

时间:2009-04-27 16:42:42

标签: java http tomcat servlets httpresponse

默认情况下,Tomcat会在遇到类似HTTP 404的内容时将一些HTML内容发送回客户端。我知道通过web.xml<error-page> can be configured来自定义此内容。< / p>

但是,我只是希望Tomcat在响应内容方面不发送任何(我当然还是喜欢状态代码)。有没有办法轻松配置?

我正在努力避免A)在我的Servlet中明确地在响应流上发送空内容,以及B)在我的web.xml中为一大堆HTTP错误状态配置自定义错误页面。

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

修改 在继续调查之后,我仍然找不到解决方案的方法。如果有人可以明确地说这是不可能的,或者提供资源证明它不起作用,我会接受这个作为答案并尝试解决它。​​

8 个答案:

答案 0 :(得分:44)

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

e.g。如果你想给出405回复,那么你做

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

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

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);
  }
}

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

答案 1 :(得分:36)

虽然这并没有完全响应&#34;不发送任何内容&#34;关于这个问题的陈述,以及Clive Evans' answer的浪潮,我发现在tomcat中你可以使那些冗长冗长的文本远离错误页面而不创建自定义的ErrorReportValve。

您可以通过2个参数&#34; showReport&#34;完成此自定义ErrorReportValve。和&#34; showServerInfo&#34;在您的&#34; server.xml&#34;:

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

Link to official documentation

在tomcat 7.0.55上为我工作,在tomcat 7.0.47上没有为我工作(我认为是因为以下链接报告的内容http://www.mail-archive.com/users@tomcat.apache.org/msg113856.html

答案 2 :(得分:10)

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

public class SecureErrorReportValve extends ErrorReportValve {

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

}

并将其设置为:

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

如果你想发送你的消息,并且只是认为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) {
        }
    }
}

答案 3 :(得分:9)

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

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

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

诀窍。使用Content-Length: 0print()即使已使用也无效,例如:

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

客户收到如下内容:

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

如果要发送一些错误消息,请使用带有消息长度的setContentLength()(非零),或者将其留给服务器

答案 4 :(得分:8)

虽然它符合Servlet规范,但出于安全考虑,我不希望tomcat或任何其他Servlet容器发送错误详细信息。我也在努力解决这个问题。搜索和尝试后,解决方案可以总结为:

  1. 正如其他人所提到的,请勿使用sendError(),而是使用setStatus()代替
  2. 框架,例如Spring Security使用sendError()虽然......
  3. 写一个Filter 一个。将呼叫重定向至sendError()setStatus()
    湾最后刷新响应以防止容器进一步修改响应
  4. A little example servlet filter doing this can be found here

答案 5 :(得分:2)

为什么不用空的HTML页面配置<error-page>元素?

答案 6 :(得分:1)

虽然这个问题有点陈旧,但我也遇到了这个问题。首先,Tomcat的行为是绝对正确的。这是每个Servlet规范。不应该改变Tomcat对规范的行为。正如Heikki Vesalainen和mrCoder所提到的,仅使用setStatussetStatus

对于可能关注的人,我使用Tomcat提出ticket来改进sendError的文档。

答案 7 :(得分:1)

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

编辑$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>
  • 即使我实际上没有为那些指定的location值(例如/400.html)创建有效的路由,也可以按我期望的那样运行

之前

enter image description here

之后

enter image description here