ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


JavaServer Pages, 3rd Edition

JSP 2.0: The New Deal, Part 2

by Hans Bergsten, author of JavaServer Pages, 3rd Edition
12/03/2003

This article is the second in a series of articles describing the features added in the JavaServer Pages (JSP) 2.0 specification. In part one, I described the new Expression Language (EL), but there's a lot more. This installment discusses the improvements made in the area of error handling and the new deployment descriptor features. I have assumed that you're familiar with JSP 1.2 and have at least heard about the JSP Standard Tag Library (JSTL).

JSP Error Pages

If you've ever tried to use a JSP error page for both JSP and servlet errors and wanted it to display or log information about the exception that caused the page to be invoked, you know that it's not so easy with JSP 1.2. The reason for the difficulties is that while both servlets and JSP pages with an errorPage declaration pass on the exception as a request attribute, they use different attribute names; only the exception passed on with the JSP attribute name is automatically exposed to the JSP error page (through the exception scripting variable and the ${pageContext.exception} EL expression).

JSP 2.0 fixes this problem by switching to the same attribute name as the servlet specification: javax.servlet.error.exception. In addition, a new property of the implicit EL pageContext variable, named errorData, exposes other information about the problem. The errorData property is an instance of the javax.servlet.jsp.ErrorData class that can be used as a bean with the following properties:

Property Java Type Description
requestURI String The URI for the request that failed.
servletName String The name of the servlet or JSP page that failed.
statusCode int The failure status code.
throwable Throwable The exception that caused the error page to be invoked.

Here's an example of a JSP error page that uses some of these properties:

<%@ page isErrorPage="true" contentType="text/html" %>
<%@ taglib prefix="log" uri="http://jakarta.apache.org/taglibs/log-1.0" %>

Sorry, but things didn't work out as planned. I've logged as much as
I know about the problem, so rest assured that my master will look
into what's wrong as soon as he's sober.

<jsp:useBean id="now" class="java.util.Date" />
<log:fatal>
  -----
  ${now}
  Request that failed: ${pageContext.errorData.requestURI}
  Status code: ${pageContext.errorData.statusCode}
  Exception: ${pageContext.errorData.throwable}
  -----
</log:fatal>

This page shows the user a somewhat reassuring message and logs the details using the Apache Jakarta Taglib project's Log tag library.

You can use the <error-page> element in the web.xml file to declare that this is as an error page for both servlets and JSP pages:

...
  <error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/error.jsp</location>
  </error-page>
  <error-page>
    <exception-code>500</exception-code>
    <location>/error.jsp</location>
  </error-page>
...

If you need to use a different error page for some specific JSP pages, you can use the page directive's errorPage attribute to selectively override the web.xml declaration in those pages:

<%@ page errorPage="/other_error.jsp" contentType="text/html" %>

Related Reading

JavaServer Pages
By Hans Bergsten

JSP Syntax Error Reporting

A subtle but important difference between JSP 1.2 and JSP 2.0 is that JSP 2.0 requires that the JSP container support the jsp:id feature, while this was just a recommendation in JSP 1.2. What does this mean to you as JSP developer? It means that you have a much better chance of getting useful error messages for JSTL and custom tag library syntax errors.

This is how it works. When the container translates a JSP page into an executable form (a servlet class), it looks at all tag libraries declared in the page. If one or more of them include a Tag Library Validator (TLV), it gives the TLV a chance to validate the page before the container accepts it. It gives the TLV an XML View of the page to analyze. The XML View is, as the name implies, a version of the page where all regular JSP elements and the template text have been converted into a well-formed XML document. The XML View is easy for the TLV to parse to ensure that all custom actions are used correctly (e.g., that they are appropriately nested and that mutually exclusive attributes aren't used for the same action element).

This is where jsp:id comes in. The container assigns an ID to each custom action element in the page and maintains a map between the ID and the element's location (file, line, and column). It adds a jsp:id attribute with this ID as the value to all custom action elements in the XML View, so that the TLV can read it. If the TLV finds an error, it includes the jsp:id attribute value for the invalid action element in the error message it returns to the container. The container can then use its mapping and add information about the location of the faulty custom action element to the error message it displays to you, making it easy to find and correct the problem.

All JSTL libraries have TLVs. I strongly recommend that you develop TLVs for the custom libraries you write, and insist that the developer of any third-party library you use do the same.

If you're unfamiliar with the XML View and TLVs, I included a brief introduction in my 2001 article about JSP 1.2 ("JSP 1.2: Great News for the JSP Community").

JSP Deployment Descriptor News

JSP 2.0 uses the deployment descriptor (web.xml) file format defined by the servlet specification, just as in earlier versions of the JSP spec. There are, however, two important changes for JSP 2.0: the rules for the web.xml file are now defined by an XML Schema, and most of the JSP-specific configuration items have been moved to a new XML element, which is under the control of the JSP specification (to minimize the coupling between the servlet and JSP specifications).

XML Schema is an XML language for describing the syntax rules for an XML document (i.e., things like how elements can be nested, what values an element can hold, value uniqueness requirements, and a lot more). It's a complex specification, but fortunately, you don't need to understand the XML Schema rule syntax to write the web.xml file, because the servlet and JSP specifications provide easier-to-understand diagrams (my JavaServer Pages, 3rd Edition book contains easy-to-read syntax charts). If you still want to learn more about XML Schema, see the W3C web site.

The main benefit of declaring the rules with XML Schema instead of the older Document Type Definition (DTD) language that was used for previous versions is that XML Schema is more expressive, so more errors can be found when parsing of the web.xml file, hopefully resulting in better portability between containers.

Another benefit, which I'm sure you'll appreciate, is that using XML Schema makes it easier to allow the top-level elements in the web.xml file to be listed in any order. With previous versions of the servlet and JSP specifications, you get an error if you, for instance, have an <error-page> element ahead of the <welcome-file-list> element; with new version, this is perfectly okay. The order of the elements within a top-level element must still be written in a strict order, though, but at least you now have free reign over the top-level elements.

All JSP-specific elements, except the <jsp-file> element nested within the <servlet> element, are now grouped together under a new top-level element named <jsp-config>. Nested within <jsp-config>, you can have <taglib> elements with the same syntax and meaning as in JSP 1.2, even though they are typically not needed with containers that implement JSP 1.2 or later, because they pick up tag library definitions automatically from all deployed JAR files.

The new <jsp-property-group> subelement is much more interesting. This element lets you apply configuration settings to a set of JSP pages that matches a specified URL pattern. For instance:

...
  <jsp-config>
    <jsp-property-group>
      <url-pattern>*.jsp</url-pattern>
      <scripting-invalid>true</scripting-invalid>
    </jsp-property-group>
  </jsp-config>
...

The <url-pattern> element identifies the set of JSP pages to which the configuration setting applies. The other nested elements define the configuration options. In this example, the <scripting-invalid> element makes it invalid to use JSP scripting elements (i.e., Java code) in all regular JSP pages.

All in all, you can use the following configuration elements within a <jsp-property-group> in the same way as the <scripting-invalid> element:

Element Description
<el-ignored> If set to true, EL expressions in the JSP pages matching the URL pattern are treated as regular text instead of as EL expressions. This is useful if you slowly migrate JSP 1.2 pages with text that looks like EL expressions to JSP 2.0. You can use a new elIgnored page directive attribute to selectively enable EL in the pages you've converted to JSP 2.0.
<scripting-invalid> If set to true, using scripting elements in a JSP page matched by the URL pattern results in translation-time errors.
<page-encoding> The specified page encoding is used for all JSP pages matching the URL pattern. This is an alternative to specifying the page encoding in every JSP page, and is the only way to use some file encodings (like EBCDIC) for JSP pages.
<include-coda> Specifies the context-relative path for a file to be automatically included at the end of all JSP pages matching the URL pattern. You can use multiple elements, within one <jsp-property-group> element or across multiple <jsp-property-group> elements.
<include-prelude> Specifies the context-relative path for a file to be automatically included at the beginning of all JSP pages matching the URL pattern. You can use multiple elements, within one <jsp-property-group> element or across multiple <jsp-property-group> elements.
<is-xml> If set to true, specifies that all JSP pages that match the URL pattern use the JSP XML syntax (i.e., they are JSP Documents).

Conclusion

In this installment, I've described the JSP 2.0 error-handling improvements and the new deployment descriptor features. Upcoming articles in this series will cover how JSP 2.0 makes it easier to use JSP for XML content and the new features related to custom tag libraries.

If you want to try out the new JSP 2.0 features, I recommend that you use Apache Tomcat 5, one of the first JSP containers to implement the new specification. A version labeled as "stable" can't be released until the final version of the specification is published, but the latest Beta versions have proved to be very stable, regardless of the Beta label. Tomcat 5 is available at the Jakarta Project site.

Hans Bergsten is the founder of Gefion Software and author of O'Reilly's JavaServer Pages, 3rd Edition.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.