I am writing a REST application using Tomcat and Spring WebMVC.
I want to signal errors to my client using HTTP status codes along with some XML payload that contains more information about what went wrong.
To catch all errors regardless of where they occur, I have written a Filter which wraps the response and overrides the sendError() method:
private static final class GenericErrorResponseWrapper
extends HttpServletResponseWrapper
{
@Override
public void sendError(int sc, String msg) throws IOException {
final HttpServletResponse wrappedResponse = (HttpServletResponse) getResponse();
wrappedResponse.setStatus(sc, msg);
wrappedResponse.setContentType("application/xml");
PrintWriter writer = wrappedResponse.getWriter();
try {
SimpleXmlWriter xmlWriter = SimpleXmlWriterWrapper.newInstance(writer);
xmlWriter.writeStartElement("ns2", "genericError")
.writeAttribute("xmlns:ns2", "http://mynamespace")
.writeCharacters(msg)
.writeEndDocument().flush();
writer.flush();
wrappedResponse.flushBuffer();
} finally {
writer.close();
}
}
}
This implementation has two problems:
- It generates a deprecation warning in Eclipse, since HttpServletResponse.setStatus(sc, msg) is deprecated.
- The HTTP response header generated by Tomcat is not correct, it starts with the first line "HTTP/1.1 500 OK". 500 is correct, but instead of OK the reason phrase should be "Internal Server Error".
How can I implement my filter so that it does the right thing and is free of deprecation warnings? Both alternatives named in the Javadoc are not usable for me:
- sendError(sc, msg) is not usable, since it commits the response body and I can't write XML payload any more
- setStatus(sc) with just the error code is theoretically usable, but it also creates the hardcoded "OK" string in the first line of the response header.