zoukankan      html  css  js  c++  java
  • Spring HandlerInterceptor的使用

     

    Spring HandlerInterceptor的使用

    标签: springexceptionobjectworkflowstringbean
    HandlerInterceptor翻译过来就是spring拦截器,它在某些功能应用上特别有用:
    
    1. 用户是否登陆以及用户权限管理 (见http://www.ideawu.net/ideablog/category4/article174.html)
    
    2. 根据用户的选择来决定是用HTML还是用Excel来作为View (该应用后面会讲解)
    
    3. blackboard building block的应用:在每一个controller之前都要生成context,在render view之后都要release context
    
     
    
    HandlerInterceptor接口有几个重要的方法:
    
    preHandleAction(ActionRequest request, ActionResponse response, Object handler):
    
    该方法会在Controller的方法执行前会被调用,可以使用这个方法来中断或者继续执行链的处理,当返回true时,处理执行链会继续,当返回false时,则不会去执行Controller的方法。(验证用户是否登陆就是使用preHandleAction方法的最好例子)
    
    afterActionCompletion(ActionRequest request, ActionResponse response, Object handler, Exception ex)
    
    preHandleRender(RenderRequest request, RenderResponse response, Object handler)
    
    postHandleRender(RenderRequest request, RenderResponse response, Object handler, ModelAndView modelAndView)
    
    这3个方法会在在controller的方法执行之后,在DispatcherServlet类导向到view进行render之前依次执行。最有用的是使用postHandleRender方法,因为它有ModelAndView 传进来,那么我们就可以在render view之前往view中添加额外的model对象,或者对view的去处进行修改(例如下面的“用HTML还是用Excel来作为View ”例子就是对view进行了更改)
    
    afterRenderCompletion(RenderRequest request, RenderResponse response, Object handler, Exception ex)
    
    该方法会在render view完成后执行,也可以说在请求过程(request processing)完成之后执行。该方法可以用来清理资源(例如象blackboard building block release context)
    
     
    
    总结一下HandlerInterceptor的流程:
    
    (DispatcherServlet maps a request to particular handler and assembles a handler execution chain consisting of the handler that is to be invoked and all of the HandlerInterceptor instances that apply to the request.)
    preHandleAction(..) is called; if the invocation of this method returns true then this workflow continues
    The target handler handles the action phase of the request (via HandlerAdapter.handleAction(..))
    afterActionCompletion(..) is called
    preHandleRender(..) is called; if the invocation of this method returns true then this workflow continues
    The target handler handles the render phase of the request (via HandlerAdapter.handleRender(..))
    postHandleRender(..) is called
    afterRenderCompletion(..) is called
     
    
    我们自己写的拦截器可以不直接实现HandlerInterceptor,而是扩展实现了HandlerInterceptor接口的具体类HandlerInterceptorAdapter,这样的话我们不需要把上面5个方法都实现,而只需要override我们需要的方法就可以了!
    
    下面举一个使用拦截器来实现“用HTML还是用Excel来作为View ”功能的例子(只列出关键代码):
    
    search.html:
    
    Search for: 
      <input type="text" name="query"><br>
    Output in: 
      <input type="radio name="format" value="xls"/>Excel or 
      <input type="radio" name="format" value="html"/>Html<br>
       
    <input type="submit"/>
     
     SearchController.Java:
    
    protected ModelAndView handleRequestInternal(
      HttpServletRequest req, HttpServletResponse response {
       
      String query = RequestUtils.getRequiredStringParameter("query");
      List shows; // retrieve shows matching the query
       
      ModelAndView mav = new ModelAndView("listshows", "shows", shows);
      return mav;
    }
    OutputFormatModificationInterceptor.java:
    
    public class OutputFormatModificationInterceptor  
    extends HandlerInterceptorAdapter {
       
      private String parameter;
      private String defaultSuffix = "";
      private Properties suffices;
       
      // setters and getters omitted 
       
      public void postHandler(
        HttpServletRequest request, HttpServletResponse response, 
        Object handler, ModelAndView mav) throws Exception {
       
        String format = request.getParameter("format");
        String suffix = suffices.getProperty(format);
        // modify view name if exists 
        if (suffix != null) {
          mav.setViewName(mav.getViewName() + suffix); //修改view达到使用不同的output格式的目的
        } else {
          mav.setViewName(mav.getViewName() + defaultSuffix);
      }
    }
    configure xml file:
    
     
    
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
           <property name="interceptors">
                  <list>
                         <ref bean="formatInterceptor"/>
                  </list>
           </property>
    </bean>
     
    <bean id="formatInterceptor" class="org.springframework.prospring.web.OutputFormatModificationInterceptor">
           <property name="suffices">
                  <props>
                         <entry key="xls">-xls</entry>
                         <entry key="html">-html</entry>
                  </props>
           </property>
     
           <property name="parameter"><value>format</value></property>
           <property name="defaultSuffix"><value>-html</value></property>
    </bean>
     
    <bean name="/listShows.action" class="org.springframework.prospring.web.controller.ListShowsController">
    ... 
    </bean>
     
     
     
    那么在blackboard building block里可以使用下面的代码:
     
    public class BbContextInterceptor extends HandlerInterceptorAdapter {
        public boolean preHandle(HttpServletRequest request,
               HttpServletResponse response, Object handler)
    throws Exception {
           Context ctx = BbServiceManager.getContextManager().setContext(request);
           request.setAttribute(requestAttributeKeyForBbContext, ctx);
          
           //check user is login or not is admin or not. if not, return false
          
           return true;
        }
     
        public void afterCompletion(HttpServletRequest request,
               HttpServletResponse response, Object handler, Exception ex)
               throws Exception {
           request.removeAttribute(requestAttributeKeyForBbContext);
           BbServiceManager.getContextManager().purgeContext();
        }
    }
     
     
  • 相关阅读:
    我为什么支持从中学课本中撤下鲁迅的文章?
    【老孙随笔】技术不行别人就不服你,怎么办?
    【老孙随笔】求职,不要无的放矢
    读者来信(1)——项目经理,不要迷信制度!
    欣闻鲁迅文章下架
    知道力读书会,欢迎大家参加
    【老孙随笔】是谁杀死了QQ?
    技术,项目经理的命?——项目经理的误区(3)
    可以不封神,但是不能不修炼——亚特兰蒂斯之神特斯拉的启示
    分布式开发2WCF如何正确调用LINQTO SQL
  • 原文地址:https://www.cnblogs.com/gym2017/p/7249492.html
Copyright © 2011-2022 走看看