[ Team LiB ] Previous Section Next Section

Recipe 9.1 Declaring Exception Handlers in web.xml

Problem

You want to display certain servlets or JSPs when a web component throws a Java exception or generates unexpected server response codes.

Solution

Use the error-page element in web.xml to specify the invocation of servlets or JSPs in response to certain exceptions or HTTP status codes.

Discussion

A Java web developer should handle these types of unexpected occurrences within his web application:

  • The "404 Not Found" server response code, which indicates that the user has made a mistake when typing in the URL, or requested a page that no longer exists.

  • The "500 Internal Server Error" that can be raised by a servlet when it calls sendError(500) on the HttpServletResponse object.

  • Runtime exceptions that are thrown by the web application and not caught by the filter, servlet, or JSP.

You configure the handling of exceptions and server response codes with the error-page element in the deployment descriptor. The error-page element in web.xml comes after any servlet, servlet-mapping, session-config, mime-mapping, and welcome-file-list elements, as well as before any taglib, resource-env-ref, resource-ref, or security-constraint elements. The error-page element includes a mapping between the status code or exception type, as well as the path to a web resource. This resource, which should be a servlet, JSP, or HTML file, should inform the user about what happened and provide links to other parts of the web site, depending on the nature of the error.

Example 9-1 shows a deployment descriptor for servlet API 2.3 that configures error pages.

Example 9-1. Configuring error pages in web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
           "http://java.sun.com/dtd/web-application_2_3.dtd"
>

<web-app>
<!-- top of deployment descriptor, such as filter, servlet, servlet-mapping, session-
config, welcome-file elements -->

<servlet>
        <servlet-name>Error404</servlet-name>
        <servlet-class>com.jspservletcookbook.Error404</servlet-class>
</servlet>

<servlet>
        <servlet-name>Error403</servlet-name>
        <servlet-class>com.jspservletcookbook.Error403</servlet-class>
</servlet>

<servlet>
        <servlet-name>ErrorIo</servlet-name>
        <servlet-class>com.jspservletcookbook.ErrorIo</servlet-class>
</servlet>

<servlet>
        <servlet-name>ErrorServlet</servlet-name>
        <servlet-class>com.jspservletcookbook.ErrorServlet</servlet-class>
</servlet>

<servlet>
        <servlet-name>ErrorGen</servlet-name>
        <servlet-class>com.jspservletcookbook.ErrorGen</servlet-class>
</servlet>

<!-- servlet mappings -->

<servlet-mapping>
        <servlet-name>Error404</servlet-name>
        <url-pattern>/err404</url-pattern>
</servlet-mapping>

<servlet-mapping>
        <servlet-name>Error403</servlet-name>
        <url-pattern>/err403</url-pattern>
</servlet-mapping>

<servlet-mapping>
        <servlet-name>ErrorIo</servlet-name>
        <url-pattern>/errIo</url-pattern>
</servlet-mapping>

<servlet-mapping>
        <servlet-name>ErrorServlet</servlet-name>
        <url-pattern>/errServ</url-pattern>
</servlet-mapping>

<servlet-mapping>
        <servlet-name>ErrorGen</servlet-name>
        <url-pattern>/errGen</url-pattern>
</servlet-mapping>

<!-- error-code related error pages -->
<!-- Not Found -->
<error-page>
    <error-code>404</error-code>
    <location>/err404</location>
</error-page>
<!-- Forbidden -->
<error-page>
    <error-code>403</error-code>
    <location>/err403</location>
</error-page>

<!-- exception-type related error pages -->

<error-page>
    <exception-type>javax.servlet.ServletException</exception-type >
    <location>/errServ</location>
</error-page>

<error-page>
    <exception-type>java.io.IOException</exception-type >
    <location>/errIo</location>
</error-page>

<! -- all other types -->
<error-page>
    <exception-type>java.lang.Throwable</exception-type >
    <location>/errGen</location>
</error-page>

<!-- web.xml continues; tag-lib, resource-ref, security-constraint elements, etc. -->

</web-app>

When a servlet throws an exception, the web container searches the configurations in web.xml that use the exception-type element for a match with the thrown exception type. In Example 9-1, if the web application throws a ServletException, then the web container invokes the /errServ servlet. The web container invokes the closest match in the class hierarchy. For example, if a servlet throws an IOException, the container invokes the /errIo servlet that is mapped to the thrown exception type, not the component mapped to java.lang.Throwable—even though IOException is in the same class hierarchy as Throwable. If this application throws an IllegalStateException, the container invokes the /errGen servlet (which is mapped to Throwable), because there is no specific error page mapping for IllegalStateException.

In the event of an HTTP response code of 403 or 404, the container invokes the web components or HTML pages mapped with the location element to those exact numbers.

The web container must return a response code of 500 if an exception occurs that is not handled by this error-page mechanism, according to the servlet API specification.


See Also

Recipe 9.2 on creating a servlet error handler; Recipe 9.3 on sending an error from a servlet; Recipe 9.4 on sending an error from a JSP; Recipe 9.5 on using JSPs to handle errors; Recipe 9.6 on declaring in a JSP that another JSP will handle its exceptions; Chapter 1 on the deployment descriptor; the Java servlet specification, which covers error handling in Chapter SRV.9.9: http://java.sun.com/products/servlet/index.html.

    [ Team LiB ] Previous Section Next Section