Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2294825
  • 博文数量: 252
  • 博客积分: 5472
  • 博客等级: 大校
  • 技术积分: 3107
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-17 18:39
文章分类

全部博文(252)

文章存档

2012年(96)

2011年(156)

分类: Java

2012-01-04 09:13:17

通过处理器映射,你可以将Web请求映射到正确的处理器Controller上。当接收到请求时,DispatcherServlet将请求交给HandlerMapping处理器映射,让它检查请求并找到一个适当的HandlerExecutionChain,这个HandlerExecutionChain包含一个能处理该请求的处理器Controller。然后,DispatcherServlet执行定义在HandlerExecutionChain中的处理器Controller。

两个最常用的处理器映射 他们都是AbstractHandleMapping的子类

1)SimpleUrlHandlerMapping

SimpleUrlHandlerMapping在应用上下文中可以进行配置,并且有Ant风格的路径匹配功能。例如,我们在applicationContext.xml中配置一个SimpleUrlHandlerMapping映射处理器:

 

  1. <beans>
  2.    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  3.       <property name="mappings">
  4.          <props>
  5.            <prop key="/**/help.do">helpAction</prop>
  6.            <prop key="/ex/view*.do">helpAction</prop>
  7.            <prop key="/*/account.do">accountAction</prop>
  8.            <prop key="/*/editAccount.do">accountAction</prop>
  9.          </props>
  10.        </property>
  11.    </bean>
  12.    <bean id="helpAction" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
  13.   
  14.    <bean id="accountAction" class="org.springframework.web.servlet.mvc.SimpleFormController">
  15.       <property name="formView" value="account"/>
  16.       <property name="successView" value="account-created"/>
  17.       <property name="commandName" value="Account"/>
  18.       <property name="commandClass" value="samples.Account"/>
  19.    </bean>
  20. <beans>

这个处理器映射首先将对所有目录中文件名为help.do的请求传递给helpAction,它是一个UrlFilenameViewController。对ex目录中所有以view开始,以.do 结尾的请求都会被传递给helpAction。同样地,我们也为accountAction定义了两个映射,所有account.do和editAccount.do的请求都将给accountAction来处理。

2)BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping是一个简单但很强大的处理器映射,它将收到的HTTP请求映射到bean的名字上。例如,为了实现一个用户新建账号的功能,我们提供了FormController和显示表单的JSP视图(或Velocity模板)。当使用BeanNameUrlHandlerMapping时,我们用如下方式将包含的访问请求映射到指定的FormController上:

  1. <beans>
  2.   <bean id="handlerMapping"
  3.       class="org.springframework.web. servlet.handler.BeanNameUrlHandlerMapping"/>
  4.   <bean name="/editAccount.do"
  5.       class="org.springframework.web. servlet.mvc.SimpleFormController">       
  6.     <property name="formView" value="account"/>
  7.     <property name="successView" value="account-created"/>
  8.     <property name="commandName" value="account"/>
  9.     <property name="commandClass" value="samples.Account"/>
  10.   </bean>
  11. <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的请求:

 

  1. <beans>
  2.    <bean id="handlerMapping"
  3.       class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  4.      <property name="interceptors">
  5.         <list>
  6.           <ref bean="officeHoursInterceptor"/>
  7.         </list>
  8.      </property>
  9.      <property name="mappings">
  10.         <props>
  11.           <prop key="/*/account.do">accountAction</prop>
  12.           <prop key="/*/editAccount.do">accountAction</prop>
  13.         </props>
  14.      </property>
  15.    </bean>
  16.    <bean id="officeHoursInterceptor" class="samples.TimeBasedAccessInterceptor">
  17.       <property name="openingTime" value="9"/>
  18.       <property name="closingTime" value="18"/>
  19.    </bean>
  20. <beans>

拦截器TimeBasedAccessInterceptor必须继承HandlerInterceptorAdapter,该拦截器的作用是,如果当前时间不是在上午9点到下午6点,它将用户重定向到某个页面:

 

  1. package samples;
  2.    public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter
  3.        {
  4.             private int openingTime;
  5.             private int closingTime;
  6.             public void setOpeningTime(int openingTime)
  7.               {
  8.                  this.openingTime = openingTime;
  9.               }
  10.            public void setClosingTime(int closingTime)
  11.               {
  12.                   this.closingTime = closingTime;
  13.               }
  14.            public boolean preHandle(
  15.                   HttpServletRequest request,
  16.                   HttpServletResponse response,
  17.                   Object handler) throws Exception {
  18.               Calendar cal = Calendar.getInstance();
  19.               int hour = cal.get(HOUR_OF_DAY);
  20.               if (openingTime <= hour < closingTime) {
  21.                   return true;
  22.               } else {
  23.                   response.sendRedirect();
  24.                   return false;
  25.               }
  26.         }
  27. }

所有的请求都将被TimeBasedAccessInterceptor截获,如果当前不在上班时间,用户会被重定向到一个静态HTML页面,提供诸如只有上班时间才能访问网站之类的告示。Spring还提供了一个adapter类HandlerInterceptorAdapter,让用户更方便的扩展HandlerInterceptor接口。

阅读(6993) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~