您的位置:首页 > 移动开发

Spring MVC组件-HandleMapping处理器映射

2016-05-12 10:34 274 查看
通过处理器映射,你可以将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接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: