If you do not want tomcat to show an error page, then do not use sendError(...). Instead use setStatus(...).
e.g. if you want to give a 405 response, then you do
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.
i.e.
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.
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.
You can accomplish to this customizing ErrorReportValve through the 2 params "showReport" and "showServerInfo" on your "server.xml":
<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)
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:
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:
@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) {
}
}
}
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:
sendError()
, use setStatus()
instead (in Jersey framework you can choose)sendError()
though...Filter
thatsendError()
to setStatus()
A little example servlet filter doing this can be found here.
As Heikki said, setting the status instead of sendError()
causes the Tomcat not touch the response entity/body/payload.
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:
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
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 setStatus
and setStatus
only.
To whom it may concern, I have raised a ticket with Tomcat to improve the docs of sendError
.
<error-page>
Elements in web.xml
Edit $CATALINA_HOME/conf/web.xml
, add at the end the following <error-page>
, save and restart 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
values (e.g. /400.html
) before
after
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With