通过处理器映射,你可以将Web请求映射到正确的处理器Controller上。当接收到请求时,DispatcherServlet将请求交给HandlerMapping处理器映射,让它检查请求并找到一个适当的HandlerExecutionChain,这个HandlerExecutionChain包含一个能处理该请求的处理器Controller。然后,DispatcherServlet执行定义在HandlerExecutionChain中的处理器Controller。
两个最常用的处理器映射 他们都是AbstractHandleMapping的子类
1)SimpleUrlHandlerMapping
SimpleUrlHandlerMapping在应用上下文中可以进行配置,并且有Ant风格的路径匹配功能。例如,我们在applicationContext.xml中配置一个SimpleUrlHandlerMapping映射处理器:
- <beans>
- <bean class=“org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”>
- <property name=“mappings”>
- <props>
- <prop key=“/**/help.do”>helpAction</prop>
- <prop key=“/ex/view*.do”>helpAction</prop>
- <prop key=“/*/account.do”>accountAction</prop>
- <prop key=“/*/editAccount.do”>accountAction</prop>
- </props>
- </property>
- </bean>
- <bean id=“helpAction” class=“org.springframework.web.servlet.mvc.UrlFilenameViewController”/>
- <bean id=“accountAction” class=“org.springframework.web.servlet.mvc.SimpleFormController”>
- <property name=“formView” value=“account”/>
- <property name=“successView” value=“account-created”/>
- <property name=“commandName” value=“Account”/>
- <property name=“commandClass” value=“samples.Account”/>
- </bean>
- <beans>
这个处理器映射首先将对所有目录中文件名为help.do的请求传递给helpAction,它是一个UrlFilenameViewController。对ex目录中所有以view开始,以.do 结尾的请求都会被传递给helpAction。同样地,我们也为accountAction定义了两个映射,所有account.do和editAccount.do的请求都将给accountAction来处理。
2)BeanNameUrlHandlerMapping
BeanNameUrlHandlerMapping是一个简单但很强大的处理器映射,它将收到的HTTP请求映射到bean的名字上。例如,为了实现一个用户新建账号的功能,我们提供了FormController和显示表单的JSP视图(或Velocity模板)。当使用BeanNameUrlHandlerMapping时,我们用如下方式将包含http://samples.com/editAccount.do的访问请求映射到指定的FormController上:
- <beans>
- <bean id=“handlerMapping”
- class=“org.springframework.web. servlet.handler.BeanNameUrlHandlerMapping”/>
- <bean name=“/editAccount.do”
- class=“org.springframework.web. servlet.mvc.SimpleFormController”>
- <property name=“formView” value=“account”/>
- <property name=“successView” value=“account-created”/>
- <property name=“commandName” value=“account”/>
- <property name=“commandClass” value=“samples.Account”/>
- </bean>
- <beans>
所有对/editAccount.do的请求就会由上面的FormController处理。要使用BeanNameUrlHandlerMapping,无须(如上所示)在Web应用上下文中定义它。在默认情况下,如果在上下文中没有找到处理器映射,DispatcherServlet会为你创建一个BeanNameUrlHandlerMapping。
3)拦截器(HandlerInterceptor)
在处理器映射中通过配置拦截器(包括处理器执行前、执行后、或者执行前后运行拦截器)将使其功能更强大。同时也可以通过自定义HandlerMapping来支持更多的功能。比如,一个自定义的处理器映射不仅可以根据请求的URL,而且还可以根据和请求相关的session状态来选择处理器。
Spring的处理器映射支持拦截器。当你想要为某些请求提供特殊功能时,例如对用户进行身份认证,这就非常有用。
处理器映射中的拦截器必须实现org.springframework.web.servlet包中的HandlerInterceptor接口,这个接口定义了3个方法,一个在处理器执行前被调用,一个在处理器执行后被调用,另一个在整个请求处理完后调用。这3个方法提供给你足够的灵活度做任何处理前后的操作。
下面的例子提供了一个拦截器,它拦截account.do和editAccount.do的请求:
- <beans>
- <bean id=“handlerMapping”
- class=“org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”>
- <property name=“interceptors”>
- <list>
- <ref bean=“officeHoursInterceptor”/>
- </list>
- </property>
- <property name=“mappings”>
- <props>
- <prop key=“/*/account.do”>accountAction</prop>
- <prop key=“/*/editAccount.do”>accountAction</prop>
- </props>
- </property>
- </bean>
- <bean id=“officeHoursInterceptor” class=“samples.TimeBasedAccessInterceptor”>
- <property name=“openingTime” value=“9”/>
- <property name=“closingTime” value=“18”/>
- </bean>
- <beans>
拦截器TimeBasedAccessInterceptor必须继承HandlerInterceptorAdapter,该拦截器的作用是,如果当前时间不是在上午9点到下午6点,它将用户重定向到某个页面:
- 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;
- }
- }
- }
所有的请求都将被TimeBasedAccessInterceptor截获,如果当前不在上班时间,用户会被重定向到一个静态HTML页面,提供诸如只有上班时间才能访问网站之类的告示。Spring还提供了一个adapter类HandlerInterceptorAdapter,让用户更方便的扩展HandlerInterceptor接口。