禁用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: 0
, print()
即使使用也不起作用,如:
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可以概括为:
- 正如别人提到的,不要使用
sendError()
,而是使用setStatus()
- 像Spring Security这样的框架使用
sendError()
虽然… - 写一个
Filter
一个。 将调用sendError()
redirect到setStatus()
湾 在最后刷新响应以防止容器进一步修改响应
一个小例子servletfilter可以在这里find 。
为什么不用一个空的HTML页面configuration<error-page>
元素?
虽然这个问题有点老,我也遇到过这个问题。 首先,Tomcat的行为是绝对正确的。 这是每个Servlet规范。 人们不应该改变Tomcat的行为。 正如Heikki Vesalainen和mrCoder所提到的,只能使用setStatus
和setStatus
。
对于谁可能关心的问题,我已经提出了一个与Tomcat的票 ,以改善sendError
的文档。