- A new dependency on J2SE 5.0(generic,annotation,auto boxing,foreach loop,varargs,static import,enum)
- Support for annotations
- Several web.xml conveniences
- A handful of removed restrictions
- Some edge case clarifications
Servlet name wildcarding
<filter-mapping>
<filter-name>Image Filter</filter-name>
<servlet-name>*</servlet-name> <!-- New -->
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Second, when writing a<servlet-mapping>
or<filter-mapping>
, you can now provide multiple match criteria in the same entry.
<filter-mapping>
<filter-name>Multipe Mappings Filter</filter-name>
<url-pattern>/foo/*</url-pattern>
<servlet-name>Servlet1</servlet-name>
<servlet-name>Servlet2</servlet-name>
<url-pattern>/bar/*</url-pattern>
</filter-mapping>
Lastly, you can now place any legal HTTP/1.1 method name into an
<http-method>
element. As you may recall,the
<http-method>
element specifies the methods on which a<security-constraint>
entry should apply.It's historically been limited to the seven standard HTTP/1.1 methods:
GET
,POST
,PUT
,DELETE
,HEAD
,OPTIONS
, andTRACE
.However, HTTP/1.1 allows for extension methods, and WebDAV is a popular technology using extensions.
With Servlet 2.5, you can now apply security constraints on any conceivable HTTP method name,
standard or extension, including WebDAV methods like
LOCK
,UNLOCK
,COPY
, andMOVE
.Just don't look for
doLock()
ordoCopy()
methods if you're writing a WebDAV servlet.You'll have to write your own
service()
method and peek at therequest.getMethod()
for dispatching. You just won't have to manage your own security, thanks to this change.
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 jobof 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()
callswithin 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 anIllegalStateException
. 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.
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 becommitted 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.
The Servlet 2.4 specification says you must call
request.setCharacterEncoding()
before callingrequest.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.
(Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader(). Otherwise, it has no effect. ---来自于jdk文档)
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.
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 descriptivemetadata-complete
. - This change has been incorporated into the above text.
- A new method
getContextPath()
was added toServletContext
. 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.