New features added to Servlet 2.5

Servlets updated with annotations, web.xml conveniences, and more

1 2 Page 2
Page 2 of 2

Servlet 2.5 eased a few restrictions around error handling and session tracking. With error handling, Servlet 2.5 removed a rule dictating that error-handling pages configured with <error-page> could not call setStatus() to alter the error code that triggered them. The rule followed the argument that the job of an error page is to report each error but not alter it. However, practical use has made clear that sometimes an error-handling page may be able to do something more graceful than show an error, perhaps choosing instead to show an online help chat window to help the user resolve the problem. The specification no longer prevents an error-page handler from producing a nonerror response.

Regarding session tracking, Servlet 2.5 eased a rule dictating that a servlet called by RequestDispatcher include() couldn't set response headers. This rule's purpose was to keep included servlets constrained within their own space on the page, unable to affect the page outside that area. The rule has eased now to allow request.getSession() calls within the included servlet, which might implicitly create a session-tracking cookie header. Logic dictates an included resource should be constrained, but logic also dictates those constraints shouldn't eliminate the ability to initiate a session. This change proves especially important for the Portlet Specification. Note that if the response was already committed, the getSession() call will throw an IllegalStateException. Previously, it would have been a no-op.

Clarifications

Lastly, the new specification clarifies several edge cases to make servlets more portable and guaranteed to work as desired.

Response closure

The first clarification is trivial and esoteric, but interesting as an example of the unintended side effects you sometimes see in a specification. The Servlet 2.4 specification dictates that the response should be committed (that is, have the response started with the status code and headers sent to the client) in several situations including when "The amount of content specified in the setContentLength method of the response and has been written to the response." This appears all well and good until you write code like this to do a redirect:

 response.setHeader("Host", "localhost");
 response.setHeader("Pragma", "no-cache");
 response.setHeader("Content-Length", "0");
 response.setHeader("Location", "http://www.apache.org"); 

The servlet technically must ignore the Location header because the response must be committed immediately as the zero byte content length is satisfied. The response is over before it began! Servlet containers often refuse to implement this behavior, and the Servlet 2.5 release adds "has been greater than zero" to the rule.

Encoding edge cases

The Servlet 2.4 specification says you must call request.setCharacterEncoding() before calling request.getReader(). However, it does not say what happens if you ignore this advice and make the setter call after the retrieval. For portability, it's now clarified to be a no-op.

Cross-context sessions

Lastly, the rules around cross-context session management have been clarified. This comes into play when servlets dispatch requests from one context to another. Within the target call, what session should be in scope, if any? The issue came up most prominently with portlets, where a main page in one context may do several include calls to portlets in another context. Servlet 2.5 now specifies that resources within a context see the session for that context, regardless of where the request may have started. This means the portlets can track their own state separate from the main page state, and this rule will apply across servlet containers.

Still on the wish list

Because of the maintenance review nature of the Servlet 2.5 release, several larger ideas had to be postponed until the next review phase. Among the ideas postponed:

  • New Input/Output (NIO) support: It's possible NIO Channels would be a more efficient way for servlets to communicate with clients.
  • Filter wrap-under or wrap-over semantics: People sometimes use filters to wrap the request and/or response objects to alter method behavior or expose new methods. When this wrapping is combined with a server's need to wrap the request and response as part of a request dispatch, how do the wraps fit together?
  • Servlets as welcome files: Should an index.do be able to act as a welcome file? Historically, the answer has been yes. But the specification doesn't clarify how to allow that functionality, especially if no index.do is on the filesystem, but a *.do mapping is, which would always exist virtually and shadow other welcome files.
  • Welcome file dispatch rules: The details on how to dispatch to welcome files have not been exhaustively specified and leave open cracks for incompatibility.
  • Selecting a default page after login: If users visit a servlet's form-based login page from their bookmarks, where should they be sent after a successful login? It's unspecified today.
  • Programmatically log in a user: Right after a user registers with a site, there's no way to inform the servlet environment about the user's credentials without the user performing a traditional login.

Update: March 6, 2006

After this article was first published, Sun issued a Servlets 2.5 MR2 (second manufacturing release) that includes a few changes from the first manufacturing release:

  • The attribute full on the <web-app> root was renamed to the more descriptive metadata-complete. This change has been incorporated into the above text.
  • A new method getContextPath() was added to ServletContext. Formerly context path information was only available in the request object, following the logic that the same context object might be bound to multiple paths so you'd only know the path at request time. However, no known servers have utilized the multiple path binding option, and a context being able to report its path is often convenient, so the method got the green light. Should it ever happen that a context be bound to multiple paths, it will return its "preferred" path.

Conclusion

If you look at the Servlet 2.5 changes apart from annotations, the new release does a nice job of giving web.xml a little syntactic sugar, of removing a few restrictions that were getting in the way, and of clarifying edge case behavior to enable more powerful and portable component-based Webpages.

The effect of annotations in Servlet 2.5 looks more dramatic. It's important to remember that servlets themselves don't define any new annotation types, and simple servlet containers don't even have to support annotations. Yet servlets authored for a JEE 5 environment will see their code change a lot from the annotation types introduced by common annotations and the EJB 3.0 and JAX-WS 2.0 specifications, and these will have a big impact on how servlets manage external resources, object persistence, and EJB components.

Jason Hunter is author of the book Java Servlet Programming, 2nd Edition (O'Reilly, 2001; ISBN: 0596000405) and coauthor of Java Enterprise Best Practices (O'Reilly, 2002; ISBN: 0596003846). He's an Apache Member and, as Apache's representative to the Java Community Process Executive Committee, he established a landmark agreement for open source Java. He's publisher of Servlets.com, an original contributor to Apache Tomcat, and cocreated the open source JDOM library to enable optimized Java and XML integration. He also designed and developed CountryHawk, a product that quickly determines a user's country based on their IP address.

Learn more about this topic

This story, "New features added to Servlet 2.5" was originally published by JavaWorld.

Copyright © 2006 IDG Communications, Inc.

1 2 Page 2
Page 2 of 2