1. Servlet name wildcardingFirst, when writing a <filter-mapping>, you can now use an asterisk in a <servlet-name> entry to represent all servlets (and thus all JSP pages as well). Previously, you could only bind one servlet at a time to a filter, like this:
Now you can bind all servlets at once:
<servlet-name>*</servlet-name> <!-- New -->
2. Multiple patterns in mappings
Second, when writing a <servlet-mapping> or <filter-mapping>, you can now provide multiple match criteria in the same entry. A <servlet-mapping> previously supported just one <url-pattern> element. Now it supports more than one.
3. Likewise, a <filter-mapping> previously allowed just one <url-pattern> or one <servlet-name>. Now it supports any number of each:
<filter-name>Multipe Mappings Filter</filter-name>
4. A new dependency on J2SE 5.0
5. Support for annotations and Annotation performanceWhether or not you use annotations—and especially if you don't—it's important to understand the performance impact they can have on a server at startup. In order for the server to discover annotations on classes, it must load the classes, which means that at startup, a server will look through all the classes in WEB-INF/classes and WEB-INF/lib, looking for annotations. (Per the specification, servers don't have to look outside these two places.) You can avoid this search when you know you don't have any annotations by specifying a metadata-complete attribute on the <web-app> root like this:
When you're not using annotations, this reenables lazy class loading.
JSR 250: Common Annotations for the Java Platform
JSR 220: Enterprise JavaBeans 3.0
JSR 224: Java API for XML-Based Web Services (JAX-WS) 2.0
JSR 181: Web Services Metadata for the Java Platform
6. A handful of removed restrictions
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.
7. Some edge case clarifications
Lastly, the new specification clarifies several edge cases to make servlets more portable and guaranteed to work as desired.
Response closureThe 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: