2

I work on a JSF application powered by Tomcat 7.0.35. I would like to create a custom error page and have therefore played with the <error-page> tag in the web.xml configuration file.

<error-page>
    <error-code>404</error-code>
    <location>/error</location>
</error-page>

It seems to work in the sense that in case of a 404, the page returned has the correct HTTP body. However the HTTP return code is 200. The expected 404 was correctly received when <error-page> was not configured.

The same soft-404 problem happens if <error-code> is not specified.

<error-page>
    <location>/error</location>
</error-page>

I am looking for a way to configure this error page without losing the error code.

Two more pieces of information that might be useful :

  • The JSF project stage is Production
  • Pretty URLs are being handled by Pretty Faces 3.3.3 with the following

    @Named(value = "error")
    @RequestScoped
    @URLMappings(mappings = {
        @URLMapping(id = "error", pattern = "/error", viewId = "/faces/error.xhtml")})
    public class ErrorController implements Serializable {
    
clark
  • 388
  • 3
  • 20

1 Answers1

2

Sometimes containers do not seem to behave very nicely when you have an Error page handled by a servlet filter. In this case it looks like you probably have mapped "/error" with PrettyFaces, and are forwarding that internally to another resource. (PrettyFaces works with Servlet forwards)

I believe what occurs here, is the container sees that new Forward, forgets that it was actually showing an error page, and sends a 200 status because the Forwarded request was successful.

What you will need to do to resolve this, is add an <action>#{bean.send404}</action> that sets the 404 status in your error page prettyfaces mapping.

<url-mapping>
   <pattern value="/error" />
   <view-id="/faces/error.xhtml" />
   <action>#{bean.send404}</action>
</url-mapping>

Then your bean method will need to get a hold of the HttpServletResponse, which ou can usually get from the FacesContext:

HttpServletResponse response = (HttpServletResponse)FacesContext.getCurrentInstance()
         .getExternalContext().getResponse();
response.sendError(HttpServletResponse.SC_NOT_FOUND);

That should do the trick for you.

Lincoln
  • 3,151
  • 17
  • 22
  • Yes, my final solution is a bit more complicated than that since I deal with the error_code but also the message, but your answer is what I needed. For future readers, you can get the request parameters for the error information from https://tomcat.apache.org/tomcat-7.0-doc/servletapi/constant-values.html – clark Apr 22 '13 at 13:38