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

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

不过,我只想让Tomcat 不要发送任何响应内容(当然,我仍然喜欢状态码)。 有什么方法可以轻松configuration这个?

我试图避免A)明确发送空的内容从我的Servlet的响应stream,和B)configuration自定义错误页面的一大堆HTTP错误状态在我的web.xml

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

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

如果你不想让tomcat显示一个错误页面,那么不要使用sendError(…)。 而是使用setStatus(…)。

例如,如果你想给405响应,那么你这样做

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

还要记住不要从你的servlet中抛出任何exception。 而是抓住exception,并再次设置statusCode你自己。

 protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { try { // servlet code here, eg 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); } } 

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

虽然这个问题并没有完全回答“不发送​​任何东西”这个问题,而且在Clive Evans的回答中 ,我发现在tomcat中,可以使那些冗长的文本远离错误页面,而不会创build一个自定义的ErrorReportValve。

你可以通过你的“server.xml”中的2个参数“showReport”和“showServerInfo”完成这个自定义的ErrorReportValve:

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

链接到官方文档 。

在tomcat 7.0.55上为我工作,没有为我在tomcat 7.0.47上工作(我想是因为在下面的链接http://www.mail-archive.com/users@tomcat.apache.org /msg113856.html )

正如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() ,或者你可以把它留给服务器

发送任何错误主体的方式,让Tomcat停止发送任何错误,快速,稍微肮脏,但简单的方法是调用setErrorReportValveClass对tomcat主机,用自定义的错误报告阀覆盖报告什么都不做。 即:

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

尽pipe它符合Servlet规范,但出于安全原因,我不希望tomcat或任何其他Servlet容器发送错误详细信息。 我也为此付出了一点努力。 search和尝试后,解决scheme可以概括为:

  1. 正如别人提到的,不要使用sendError() ,而是使用setStatus()
  2. 像Spring Security这样的框架使用sendError()虽然…
  3. 写一个Filter
    一个。 将调用sendError()redirect到setStatus()
    湾 在最后刷新响应以防止容器进一步修改响应

一个小例子servletfilter可以在这里find 。

为什么不用一个空的HTML页面configuration<error-page>元素?

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

对于谁可能关心的问题,我已经提出了一个与Tomcat的票 ,以改善sendError的文档。