Java Server Pages update

JSP HAS GROWN very popular, as shown by the sheer volume of presentations at this year's JavaOne conference. In this column, I will cover various aspects of JSP development and show how to use this technology to its fullest. I will begin with an update as to what's happening with JSP, which has undergone several important changes.

Changes to the API
Sun has recently updated the JSP API to release 1.2 and published errata to the 1.1 specifications. Likewise, the underlying Servlet API has been updated to release 2.3. Some of the important changes are as follows:

Java 2, Version 1.2 now a requirement—Previous versions of JSP were based on the 1.1 JDK, even though they worked fine under Java 2 JDK Versions 1.2 and 1.3. Starting with the latest release of the API, however, Sun has firmly tied JSP to the Java 2 family by requiring JDK 1.2 or higher as the underlying technology.

Servlet API 2.3 required—Since JSP is an extension of the Servlet API, it is linked to the new version, 2.3. However, an explicit requirement of the 2.3 API is that containers must maintain backwards-compatibility with the 2.2 API, as well as the 2.2 deployment descriptor for Web applications. This ensures that existing applications will continue to function under the newer containers.

XML syntax now fully supported—There has always been a close relationship between XML and JSP, and it was assumed that a full XML syntax would be required to enable parsing and generation of JSP content by page authoring tools. With JSP 1.2, the XML syntax is now fully developed; there is an XML representation for all of the page elements, including the raw content. Here's an example of the XML version of an HTML "Hello World" page:


<jsp:root
  xmlns:jsp"http://java.sun.com/JSP/Page"
  version="1.2">
<jsp:text><!-[CDATA[<html>
<title>My Page</title>
<body>
<jsp:include page="top_banner.jsp"/>
Hello World.
</body>
]]</jsp:text>
The ability to express a JSP page fully in XML provides a number of capabilities. It allows a machine-friendly format for page authoring tools, automated validation of the document structure, and the ability to use technology like XSL to convert data directly into a JSP form. This is a big step in allowing tool vendors to take JSP into the mainstream.

Determining the real path—One inconsistency that arose with the WAR format was the concept of determining the path to a request file via the getRealPath method of the request object. This method doesn't mean anything if the Web application is run directly from a WAR file. The new specification says that in such a case it should now return null if unable to determine an actual path to the resource. All in all, you probably want to avoid this method if you can.

Redirects are not relative to the servlet context—A clarification to Servlet API 2.2 was made to indicate that the sendRedirect method of the HttpServletResponse class should operate relative to the context root of the Web server ("/"), rather than relative to the context root of the servlet as some container vendors had surmised. To redirect to a URL relative to your servlet context, simply prepend the context path.

Restricted names—There was some contention as to which prefixes were reserved words in JSP. JSP 1.2 clears this up, stating that the prefixes jsp, _jsp, java, and sun cannot be used as the prefix in taglib directives, as element names used in actions, as attribute names, or in request parameters. This entire namespace is reserved for internal usage, and should not be used by application developers.

Page encoding attribute—The 1.2 JSP API adds a new attribute to the page directive called pageEncoding. This new attribute allows users to specify the page encoding separately from the content type of the page, improving readability. It defaults to the encoding specified in the contentType attribute, if present; otherwise, the default encoding of ISO8859-1 (Latin-1) is used.

Flush on include no longer required on include—Prior to JSP 1.2, the <jsp:include> tag required a flush attribute with a value of true. As soon as users attempted to perform an inclusion, the buffer would be flushed and the output committed, preventing users from setting any response headers (such as setting cookies or redirecting the request) via the included page. The attribute now defaults to a value of false and is optional.

Web Application Changes
JSPs are packaged into Web applications (WARs) as defined in the Servlet API. Therefore, changes made to the Web application format as part of Servlet API 2.3 are likely to affect JSP developers.

New 2.3 Web application Document Type Definition (DTD)—Along with the new API comes a new DTD to specify in the deployment descriptor. This helps the container to distinguish between Version 2.3 and 2.2 applications, and validate the descriptor appropriately.

Handling of whitespace—Servlet containers are now required to be more lenient of whitespace in the deployment descriptor. They must ignore any leading or trailing whitespace surrounding PCDATA.

Resolving path names in the web.xml file—Several clarifications and additions were made to the specifications regarding the handling of path names in the deployment descriptor. All paths are considered to be in decoded form. Any references to resources stored within a WAR (i.e., images or other data files) must be referenced absolutely, starting with a "/".

Request mappings—Prior to the 2.3 API, there was confusion surrounding several elements of the request mapping facilities that has since been clarified. If you map a servlet to an entire directory hierarchy (i.e., /private/*), the specification now states explicitly that it should match a request to /private. Another clarification is that request matching is case-sensitive, so a request for /userInfo is different than a request for /userinfo.

Dependency on installed extensions—The new JSP API recognizes the difficulty of managing the installed extensions required by a Web application and addresses this issue with a series of recommendations to container developers. Containers should support a facility for easily adding extensions (in the form of jar files) to all of the container's applications, as well as a method for validating required extensions through an optional manifest file in the WAR.

Custom Tag Improvements
The addition of custom tag capabilities in the 1.1 API created lots of excitement in the development community. An effort is already well underway to define a standard set of tags that would be available in all containers. Several new capabilities have made it into the new API to help proliferate custom tags.

Translation time validation—A new element, <validator>, has been added to support translation time validation. This element uses the <validator-class> element to define a class that can be used to validate the proper use of tags in a document. It allows users to enforce rules about which tags can appear where and in what combinations.

New tag interfaces—A new custom tag interface, IterationTag, provides a convenient way to create looping related custom tags, while the TryCatchFinally, which can be implemented by any tag, improves exception-handling capabilities.

Changes to the Tag Library Descriptor (TLD)—The TLD is an XML document that tells the JSP container about the custom tags users have written. Several important changes to the TLD DTD have been made in Version 1.2 of the JSP API.

New <variable> element—A new <variable> element is available to specify any scripting variables defined by a custom tag. This tag obviates the need for a TagExtraInfo class in many cases and improves translation time validation capabilities.

<jsp-version> element now required—The <jsp-version> element is used to specify the minimum version of the JSP API the tag library supports. This element was optional in JSP 1.1, but is now required. This will prevent conflicts between tag libraries and their containers as the technology continues to progress. The TLD is not compatible with the Version 1.1 TLD, but servlet containers are required to support both formats.

Improved documentation elements—In JSP 1.2, the TLD has been extended to allow more detailed documentation about the tags. A new optional element, <example>, has been added to the <tag> element. This element can be used to specify an intended usage of the tag and to give the user some clue about how to use it. The <info> element, which has always existed for the <tag> element, has been renamed <description> and can now be used on the <variable>, <attribute>, and <validator> elements. The TLD can be read by a page authoring tool or translated directly into documentation via XSL, similar to how javadoc turns Java source into API documentation.

JavaBean Changes
JavaBeans, the component model for JSP development, has not changed much in the new API, but several important clarifications have been made.

Bean tags cannot implicitly access scriptlet objects—In some vendor's implementations, the <jsp:getProperty> and <jsp:setProperty> tags could access variables defined by scriptlets and custom tags, while others could not because the JSP tags in some containers interact only with objects stored in the page context. The specification now clearly states these tags should work with the page context exclusively. If custom tags or scriptlets wish to expose any objects they create to these tags, they must explicitly do so by adding them to the page context.

Fully qualified class names required—Some early JSP implementations honored import statements in the <jsp:useBean> tag and allowed class names that were not fully qualified in this tag. This has been clarified in Version 1.2 and is no longer allowed. Even if a container supports this shortcut, users should always fully qualify their class names to keep the code compatible with other containers or updates to their own. Note that for scripting variables, imported packages are supported and fully qualified class names are not required.

New Servlet Features
Two new features of the Servlet API—servlet filters and application events—will prove especially useful in building JSP applications.

Servlet filters—This feature is based on a non-standard feature seen in the early servlet container precursors called servlet chaining. With servlet filters, users can define special filter classes that can interact with the request headers and content prior to the servlet or JSP receiving the request. Filters can also be applied to the response from a servlet or JSP to perform additional processing. Multiple filters can be applied to given sets of requests at deployment time, without the underlying servlet or JSP having any knowledge of the filters presence. This will become the way to add authentication, logging, and encryption capabilities to Web applications of the future.

Application events—Application-level events provide a mechanism for responding to signals about the state of the servlet container and the servlet application life cycle. For example, code can be informed just prior to a servlet context being initialized, any time attributes are added to the application scope, or when a new session is created. It provides for a much more cohesive Web application than was previously possible.

Conclusion
The changes to the JSP API focus on fixing some rough spots in the language, improving custom tags, and better preparing the technology for tool support. With the adoption of JSP assured, tool vendors are now scrambling to incorporate JSP capabilities into their feature sets. One of the most important new features in JSP 1.2—support for an XML representation of the page—enables much improved tool support, and I predict this will lead to a bountiful crop of new page authoring tools this year.

In future articles, I'll discuss some of these new features and demonstrate how to best apply them to building Web applications for J2EE. It also remains to be seen how quickly server vendors will implement these new features. I'm willing to bet that several containers will already be supporting the new APIs by the time you read this article.