Skip to main content

Redirect JSF resource request to custom HTTP status 404 error page

3 replies [Last post]
dtb
Offline
Joined: 2012-02-14
Points: 0

Hello!

Is there a way to redirect a JSF resource request for a non-existent resource to a custom 404 status code error page?

Specifically, when specifying directly in browser a url like http://host:port/appname/javax.faces.resource/non-existent-page.xhtml, I want the user to be redirected to a custom error page.

In the web.xml, I have specified the following:

<error-page>
    <error-code>404</error-code>
    <location>/pages/error/pageNotFound.xhtml</location>
</error-page>

The JSF servlet mapping is:

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

I also made the resource requests to be unsecured:

<security-constraint>
     <web-resource-collection>
        <web-resource-name>Unsecured resources</web-resource-name>
        <url-pattern>/javax.faces.resource/*</url-pattern>
     </web-resource-collection>
</security-constraint>

The redirect to my custom error page works well for all requests except those containing /javax.faces.resource/* (I guess where ResourceHandler is implied). I studied the source code for FacesServlet. In its service() method, when a

request for non-existing resource is made, the method ResourceHandler.handleResourceRequest() is beeing called, which in turn calls HttpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND). The documentation on HttpServletResponse

reads "This method is used to set the return status code when there is no error (for example, for the status codes SC_OK or SC_MOVED_TEMPORARILY). If there is an error, and the caller wishes to invoke an error-page defined in the web

application, the sendError method should be used instead." From this I conclude that this is the reason why my custom page gets never called.

Does any workaround exist to this behavior? I need to redirect to my custom page with the purpose to hide the version of Tomcat, which is displayed on the default 404 HTTP status page.

I'm using the following environment:

  • Apache Tomcat 7.0.19
  • Mojarra 2.1.2 JSF implementation

Thank you in advance!

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mriem
Offline
Joined: 2004-03-26
Points: 0

Hi there,

The main resason why it is using setStatus instead of sendError is because a resource request
is a request that is always triggered from a main page. If it is not found it will set the status
of 404 and a short body that indicates the resource is not found.

If you want to hide the version of Tomcat, you probably want to look at the Tomcat documentation,
specifically the security related documentation. Start here: http://tomcat.apache.org/tomcat-7.0-doc/security-howto.html

Manfred

dtb
Offline
Joined: 2012-02-14
Points: 0

Thanks for the tip!

I looked at the documentation on Tomcat security. And at least, I found how to hide the information about the container's name and version. I'll implement this as a temporary workaround. However it would be great to be able to redirect to some custom page, to make all error pages consistent across application.

mriem
Offline
Joined: 2004-03-26
Points: 0

If you think the resource handling is insufficient, please file an enhancement request at the JSF bug tracker.