当前位置: 代码迷 >> 综合 >> spingmvc interceptor
  详细解决方案

spingmvc interceptor

热度:99   发布时间:2023-12-10 21:39:36.0

interceptor:一个拦截器

拦截器:是springmvc框架中的一种对象,类似过滤器。 拦截器的主要作用是拦截用户的请求。
可以截断请求,不被处理。 所以可以使用拦截器做登录的验证,权限的检查,日志打印。

拦截器的执行时间:在适配器对象获取之后,在处理器方法执行之前。拦截用户的请求。

拦截器的数量:在一个项目中拦截器可以有0到多个。 拦截器是全局的,对象项目中的所有Controller都可以使用拦截器。

拦截器的创建:
1.新建类,实现框架的中接口HandlerInterceptor, HandlerInterceptor是拦截器接口
2.springmvc配置文件中,声明拦截器的对象, 并指定拦截的请求uri地址
在这里插入图片描述

public class MyInterceptor implements HandlerInterceptor {private long btime;/*** preHandle:预处理方法,请求首先到达此方法。可以在方法中对请求做判断,处理。*            在处理器方法之前执行的。*  * 参数:*   Object handler : 处理器对象。* 返回值: boolean*   true:请求是正确的,可以被处理。请求可以通过拦截器*      拦截器MyInterceptor的【preHandle】====执行MyController处理器的doSome()====拦截器MyInterceptor的 【postHandle】拦截器MyInterceptor的 【afterCompletion】*   false:请求是不正确的,不能被处理。 请求被截断。*    拦截器MyInterceptor的【preHandle】*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception {btime = System.currentTimeMillis();System.out.println("拦截器MyInterceptor的【preHandle】");//request.getRequestDispatcher("/result.jsp").forward(request, response);return true;}/*** postHandle:后处理方法。在处理器方法执行之后执行的。 可以获取到处理器方法的返回值* ModelAndView,*            可以修改Model中的数据, 修改视图View. 对请求的处理结果做二次修改。*            参数:*   Object handler : 处理器对象。*   ModelAndView mv: 处理器方法的返回值, 也就是请求的处理结果*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView mv) throws Exception {System.out.println("拦截器MyInterceptor的 【postHandle】");//对请求的处理结果做二次的修正if( mv != null){//修改数据mv.addObject("mydate", new Date());//修改视图mv.setViewName("other");			}}/*** afterCompletion:最后执行的方法。在视图View对象处理完成后执行的。 *                 此方法执行,意味着请求处理完成。*                 只要当前拦截器的preHandle返回true,afterCompletion方法一定执行。*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)	throws Exception {System.out.println("拦截器MyInterceptor的 【afterCompletion】");//最后执行的,一般做资源回收, 内存的释放。long etime = System.currentTimeMillis();System.out.println("请求的处理时长:"+(etime -btime));}
}

多个拦截器情况下执行顺序
在这里插入图片描述
执行结果
在这里插入图片描述

执行流程解析:
在这里插入图片描述

源代码:

查看中央调度器 DispatcherServlet 的 doDispatch()方法源码:在执行处理器方法之前,
会执行处理器执行链对象 mappedHandler 的 applyPreHandle()方法。然后执行 Handler,最后
执行处理器执行链对象的 applyPostHandle()方法。

在这里插入图片描述

applyPreHandle()方法用于执行处理器执行链中的所有拦截器的 preHandle() 方法。
applyPreHandle()方法的返回结果取决于执行链中的每一个拦截器的 preHandle()方法。只要
有一个 preHandle()方法返回 false,则其就会返回 false。然后就执行了 return;即结束了
doDispatch()方法,即该请求的处理结束。

在这里插入图片描述

对 于 处 理 器 执 行 链 的 applyPostHandle() 方 法 , 
其 是 循 环 倒 序 执 行 所 有 拦 截 器 的postHandle()方法的。

在这里插入图片描述

那么 afterCompletion()方法是什么时候执行的呢?
在 刚 才 的 处 理 器 执 行 链 的 applyPreHandle() 方 法 中 看 到 , 若 存 在 任 一个拦截器的
preHandle()方法返回 false,则会调用执行处理器执行链的 triggerAfterCompletion()方法,即
会触发所有 afterCompletion()方法的执行。
在 doDispatch()方法中也存在一个 catch(){}语句,表示若发生异常,则会调用执行
triggerAfterCompletion()方法。

在这里插入图片描述

但在正常情况下,即所有的 preHandle()方法返回均为 true,且 doDispatch()方法没有异
常发生的情况下,afterCompletion()方法是在视图解析器后执行的。
查看中央调度器 DispatcherServlet 的 processDispatchResult()方法源码可知,在对视图渲
染 过 后 , 会 调 用 执 行 处 理 器 执 行 链 的 triggerAfterCompletion() 方 法 , 即 执 行 所 有 的
afterCompletion()方法。

在这里插入图片描述

打 开 处 理 器 执 行 链 的 triggerAfterCompletion() 方 法 , 可 以 看 到 , 其 对 拦 截 器 的
afterCompletion()方法的执行,也是循环倒序执行的。

在这里插入图片描述

哥哥们 我尽力了
在这里插入图片描述

  相关解决方案