Spring HandlerInterceptor的使用

xiaoxiao2021-02-28  99

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 continuesThe target handler handles the action phase of the request (via HandlerAdapter.handleAction(..))afterActionCompletion(..) is calledpreHandleRender(..) is called; if the invocation of this method returns true then this workflow continuesThe target handler handles the render phase of the request (via HandlerAdapter.handleRender(..))postHandleRender(..) is calledafterRenderCompletion(..) 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();     } }
转载请注明原文地址: https://www.6miu.com/read-80822.html

最新回复(0)