In previous versions of Spring, users were required to define
HandlerMapping
s in the web application
context to map incoming web requests to appropriate handlers. With the
introduction of Spring 2.5, the
DispatcherServlet
enables the
DefaultAnnotationHandlerMapping
, which looks for
@RequestMapping
annotations on
@Controllers
. Typically, you do not need to
override this default mapping, except when overriding the properties.
These properties are:
interceptors
: List of interceptors to use.
HandlerInterceptor
s are discussed in
Section 15.4.1, “Intercepting requests - the
HandlerInterceptor interface”.
defaultHandler
: Default handler to use, when
this handler mapping does not result in a matching handler.
order
: Based on the value of the order
property (see the org.springframework.core.Ordered
interface), Spring sorts all handler mappings available in the context
and applies the first matching handler.
alwaysUseFullPath
: If
true
, Spring uses the full path within the current
servlet context to find an appropriate handler. If
false
(the default), the path within the current
servlet mapping is used. For example, if a servlet is mapped using
/testing/*
and the
alwaysUseFullPath
property is set to true,
/testing/viewPage.html
is used, whereas if the
property is set to false, /viewPage.html
is
used.
urlDecode
: Defaults to
true
, as of Spring 2.5. If
you prefer to compare encoded paths, switch this flag to
false
. However, the
HttpServletRequest
always exposes the
servlet path in decoded form. Be aware that the servlet path will not
match when compared with encoded paths.
lazyInitHandlers
: Allows lazy initialization
of singleton handlers (prototype handlers are
always lazy-initialized). The default value is
false
.
Note | |
---|---|
The
|
The following example shows how to override the default mapping and add an interceptor:
<beans> <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <bean class="example.MyInterceptor"/> </property> </bean> <beans>
Spring's handler mapping mechanism includes handler interceptors, which are useful when you want to apply specific functionality to certain requests, for example, checking for a principal.
Interceptors located in the handler mapping must implement
HandlerInterceptor
from the
org.springframework.web.servlet
package. This
interface defines three methods: one is called
before the actual handler is executed; one is
called after the handler is executed; and one is
called after the complete request has finished.
These
three methods should provide enough flexibility to do all kinds of
preprocessing and postprocessing.
The preHandle(..)
method returns a boolean
value. You can use this method to break or continue the processing of
the execution chain. When this method returns true
,
the handler execution chain will continue, when it returns false, the
DispatcherServlet
assumes the interceptor itself
has taken care of requests (and, for example, rendered an appropriate
view) and does not continue executing the other interceptors and the
actual handler in the execution chain.
The following example provides an interceptor that intercepts all requests and reroutes the user to a specific page if the time is not between 9 a.m. and 6 p.m.
<beans> <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="officeHoursInterceptor"/> </list> </property> <property name="mappings"> <value> /*.form=editAccountFormController /*.view=editAccountFormController </value> </property> </bean> <bean id="officeHoursInterceptor" class="samples.TimeBasedAccessInterceptor"> <property name="openingTime" value="9"/> <property name="closingTime" value="18"/> </bean> <beans>
package samples; public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { private int openingTime; private int closingTime; public void setOpeningTime(int openingTime) { this.openingTime = openingTime; } public void setClosingTime(int closingTime) { this.closingTime = closingTime; } public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Calendar cal = Calendar.getInstance(); int hour = cal.get(HOUR_OF_DAY); if (openingTime <= hour < closingTime) { return true; } else { response.sendRedirect("http://host.com/outsideOfficeHours.html"); return false; } } }
Any request coming in is intercepted by the
TimeBasedAccessInterceptor
. If the current time
is outside office hours, the user is redirected to a static HTML file
that says, for example, you can only access the website during office
hours.
As you can see, the Spring adapter class
HandlerInterceptorAdapter
makes it easier to
extend the HandlerInterceptor
interface.