This issue applies to the "jersey-servlet" module.
In current versions of Jersey, any error with a status code above 400 is sent to the container with "sendError". See WebComponent.java#finish and ServletContainer.java#service. This has the effect that responses with a status code >= 400 is sent to the underlying container for further processing, i.e. using the <error-page> directives in web.xml. setStatus would not deliver it to the container. See http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html#setStatus(int).
This use of sendError seems to be introduced in
JERSEY-389 and is probably desirable for many projects, however, other projects may always want to use setStatus over sendError. I'll give an example that applies to my current project:
- JSF and Jersey is used in the same webapplication. In the context of JSF-errors, we use web.xml <error-page> directives for error handling (e.g. 403) and <error-page> with <exception-type>java.lang.Throwable</exception-type> for top level exception handling. These directives return HTML, and in the case of some errors, go via JSF first generate the HTML. Depending on the error, some may contain redirects to the login page.
- For Jersey we use ExceptionMappers and ExceptionMapper<Exception> as the top level error handling. Although the correct status code is returned, it will be delivered to the container since sendError is returned. If the status code matches with one defined in web.xml, the container will proceed with these <error-page> directives. This has the undesired effect of a) returning HTML to the client, b) possibly giving redirects and the login page in return, c) triggering code in JSF or an other framework if the <error-page> is set to a servlet page.
From a API consumer perspective, we want to always return valid JSON/XML to the client without side effects from <error-page> directives.
Suggestion: an init-param to jersey that toggles between todays behavior and always using setStatus to avoid container error handling.