springMVC之Interceptor拦截器
转自:https://blog.csdn.net/qq_25673113/article/details/79153547
Interceptor拦截器用于拦截Controller层接口,表现形式有点像Spring的AOP,但是AOP是针对单一的方法。Interceptor是针对Controller接口以及可以处理request和response对象。
1 HandlerInterceptor接口的定义
我们先来看下HandlerInterceptor接口的定义,定义了三个接口,分别是preHandle、postHandle、afterCompletion。
1 public interface HandlerInterceptor { 2 3 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 4 throws Exception; 5 6 void postHandle( 7 HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 8 throws Exception; 9 10 void afterCompletion( 11 HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 12 throws Exception; 13 14 }
preHandle是调用Controller之前被调用,当返回false后,会跳过之后的拦截器,并且不会执行所有拦截器的postHandle,并调用返回true的拦截器的afterCompletion方法。
postHandle是调用Controller之后被调用,但是在渲染View页面之前。
afterCompletion是调用完Controller接口,渲染View页面最后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法,顺序相反。
和HandlerInterceptor很相似的要有一个AsyncHandlerInterceptor接口,只是多了个afterConcurrentHandlingStarted个方法,当接口使用了异步的方法的时候调用。
1 public interface AsyncHandlerInterceptor extends HandlerInterceptor { 2 3 void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) 4 throws Exception; 5 6 }
2 HandlerInterceptor接口的定义
2.1 DispatcherServlet里doDispatch主处理逻辑
DispatcherServlet里doDispatch()就是springMVC的处理主要逻辑。因此肯定包含了拦截器的主要处理逻辑
1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 try { 3 4 try { 5 //.......省略代码 6 7 //返回HandlerExecutionChain 其中包含了拦截器队列 8 mappedHandler = getHandler(processedRequest); 9 10 //调用拦截器PreHandle方法,若返回false不执行Controller逻辑,并不调用下面的PostHandle方法 11 if (!mappedHandler.applyPreHandle(processedRequest, response)) { 12 return; 13 } 14 15 // 处理Controller层 16 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 17 18 applyDefaultViewName(processedRequest, mv); 19 20 //调用拦截器的PostHandle方法 21 mappedHandler.applyPostHandle(processedRequest, response, mv); 22 } 23 catch (Exception ex) { 24 dispatchException = ex; 25 } 26 27 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); 28 } 29 catch (Exception ex) { 30 //抛出异常后都会调用拦截器AfterCompletion方法 31 triggerAfterCompletion(processedRequest, response, mappedHandler, ex); 32 } 33 finally { 34 if (asyncManager.isConcurrentHandlingStarted()) { 35 // Instead of postHandle and afterCompletion 36 if (mappedHandler != null) { 37 //若Controller方法为异步调用,则执行拦截器afterConcurrentHandlingStarted(只有AsyncHandlerInterceptor拦截器才有) 38 mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); 39 } 40 } 41 } 42 }
2.2 获取拦截器
1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 //返回HandlerExecutionChain 其中包含了拦截器队列 3 mappedHandler = getHandler(processedRequest); 4 } 5 //返回HandlerExecutionChain 6 public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { 7 8 HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); 9 return executionChain; 10 } 11 12 protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { 13 HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? 14 (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); 15 16 //根据url和拦截器异常的配置url做对比,若符合则加入队列 17 String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); 18 for (HandlerInterceptor interceptor : this.adaptedInterceptors) { 19 if (interceptor instanceof MappedInterceptor) { 20 MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; 21 if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { 22 chain.addInterceptor(mappedInterceptor.getInterceptor()); 23 } 24 } 25 else { 26 chain.addInterceptor(interceptor); 27 } 28 } 29 return chain; 30 } 31 32 public boolean matches(String lookupPath, PathMatcher pathMatcher) { 33 PathMatcher pathMatcherToUse = (this.pathMatcher != null) ? this.pathMatcher : pathMatcher; 34 if (this.excludePatterns != null) { 35 for (String pattern : this.excludePatterns) { 36 if (pathMatcherToUse.match(pattern, lookupPath)) { 37 return false; 38 } 39 } 40 } 41 if (this.includePatterns == null) { 42 return true; 43 } 44 else { 45 for (String pattern : this.includePatterns) { 46 if (pathMatcherToUse.match(pattern, lookupPath)) { 47 return true; 48 } 49 } 50 return false; 51 } 52 }
上述的拦截器的信息,都来自与下面的配置文件
1 <!-- 拦截器链 --> 2 <mvc:interceptors> 3 4 <mvc:interceptor> 5 <!--拦截器mapping 符合的才会执行拦截器--> 6 <mvc:mapping path="/**"/> 7 <!--在拦截器mapping中除去下面的url --> 8 <mvc:exclude-mapping path="/transactional_test/*"/> 9 <!--执行的拦截器--> 10 <ref bean="apiInterceptor"/> 11 </mvc:interceptor> 12 </mvc:interceptors> 13 14 <bean id="apiInterceptor" class="com.lk.dome.interceptor.ApiInterceptor"/> 15 ---------------------
2.3 处理拦截器
1 boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 HandlerInterceptor[] interceptors = getInterceptors(); 3 if (!ObjectUtils.isEmpty(interceptors)) { 4 for (int i = 0; i < interceptors.length; i++) { 5 HandlerInterceptor interceptor = interceptors[i]; 6 //若返回false,则直接执行拦截器的triggerAfterCompletion方法 7 if (!interceptor.preHandle(request, response, this.handler)) { 8 triggerAfterCompletion(request, response, null); 9 //直接返回,在外层的doDispatch逻辑中不执行后面的逻辑 10 return false; 11 } 12 //记录成功执行的拦截器个数 13 this.interceptorIndex = i; 14 } 15 } 16 return true; 17 } 18 void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { 19 HandlerInterceptor[] interceptors = getInterceptors(); 20 if (!ObjectUtils.isEmpty(interceptors)) { 21 //拦截器队列从后往前之心,顺序相反 22 for (int i = interceptors.length - 1; i >= 0; i--) { 23 HandlerInterceptor interceptor = interceptors[i]; 24 interceptor.postHandle(request, response, this.handler, mv); 25 } 26 } 27 } 28 void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) 29 throws Exception { 30 31 HandlerInterceptor[] interceptors = getInterceptors(); 32 if (!ObjectUtils.isEmpty(interceptors)) { 33 //interceptorIndex为执行成功的拦截器标志 34 for (int i = this.interceptorIndex; i >= 0; i--) { 35 HandlerInterceptor interceptor = interceptors[i]; 36 try { 37 interceptor.afterCompletion(request, response, this.handler, ex); 38 } 39 catch (Throwable ex2) { 40 logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); 41 } 42 } 43 } 44 } 45 //异步方法调用,拦截器必须属于AsyncHandlerInterceptor接口 46 void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) { 47 HandlerInterceptor[] interceptors = getInterceptors(); 48 if (!ObjectUtils.isEmpty(interceptors)) { 49 for (int i = interceptors.length - 1; i >= 0; i--) { 50 if (interceptors[i] instanceof AsyncHandlerInterceptor) { 51 try { 52 AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i]; 53 asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler); 54 } 55 catch (Throwable ex) { 56 logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted", ex); 57 } 58 } 59 } 60 } 61 }
转载于:https://www.cnblogs.com/sharpest/p/10416198.html
springMVC之Interceptor拦截器相关推荐
- 框架:SpringMVC中Interceptor拦截器的两种实现
Spring中使用Interceptor拦截器 SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证, ...
- SpringMVC中使用Interceptor拦截器
2019独角兽企业重金招聘Python工程师标准>>> SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理. ...
- Springmvc中的拦截器interceptor及与过滤器filter的区别
一.Springmvc中的拦截器概述及与过滤器filter的区别 1).Springmvc中的拦截器interceptor用于对控制器controller进行预处理和后处理的技术; 2).可以定义拦截 ...
- 在SpringMVC中使用拦截器(interceptor)拦截CSRF***
关于什么是CSRF我这里就不多说了,以前转载的一篇文章(PS:https://www.zifangsky.cn/358.html)已经说得很清楚了.这里只是简单介绍如何在SpringMVC中使用拦截器 ...
- SpringMVC中的拦截器
SpringMVC中的拦截器 拦截器的作用 Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理. 用户可以自己定义一些拦截器来实现 ...
- spring拦截器覆盖_Spring中使用Interceptor拦截器
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- 【Java代码】使用 org.apache.ibatis.plugin.Interceptor 拦截器实现全局 mapper.xml 参数注入(可用于切换数据库实例schema+Demo举例源码)
1. why 项目没有使用MyBatis,进行数据操作时使用的是jdbc中默认的schema,现在项目要加入多租户,同一个数据库下不同租户使用不同的实例schema,这就要在mapper文件内所有 ...
- (转)SpringMVC学习(十二)——SpringMVC中的拦截器
http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...
- 【Java从0到架构师】SpringMVC - 异常处理_拦截器
异常处理_拦截器 异常处理 简单的异常与页面映射 - SimpleMappingExceptionResolver √自定义异常处理类 - 实现 HandlerExceptionResolver 接口 ...
最新文章
- 爬虫进阶教程:极验(GEETEST)验证码破解教程
- 2022版全球及中国煤矿机械再制造行业“十四五”发展规划与投资建议报告
- 【NLP】新分类!全总结!最新Awesome-SLU-Survey资源库开源!
- AI大神贾扬清确认将离开Facebook,加入阿里硅谷研究院
- 我的技术家园,吸取精神食粮的天堂
- WSS Alert(邮件提醒) 定制
- platform_SpringOne Platform 2016回顾
- Apache TomEE + JMS。 这从未如此简单。
- 关于linux用户权限的理解
- 由PPPOE看Linux网络协议栈的实现
- 吓坏了!智能锁半夜自己“离奇打开”
- 用户注册与登陆(验证和数据库)
- 机器学习基础(五十五)—— 核(Kernel Trick)
- python学出来能做什么-python学出来能做什么
- Oracle SUn
- 更新macOS Big Sur系统后,Parallels Desktop打不开怎么办?教你解决方法!
- RxBus的使用及解析
- 字节跳动小程序平台审核常见被拒情形
- C51单片机实现呼吸灯
- 那些踩过的declared implicitly的坑
热门文章
- linux中的NFS服务器配置及/etc/exports
- org manual翻译--3.5.8 更新表格
- hdu2716水水哈希
- mass Framework event模块 v8
- python求1到n的乘积_Python简单实现两个任意字符串乘积的方法示例
- 未定义标识符 stringc/c++(20)_20款奔驰G63AMG霸气颜值 运动造型
- Nginx —— ngx_http_core_module 模块提供的变量
- vue 使用element 菜单与tab页联动
- 秀尔算法:破解RSA加密的“不灭神话” --zz
- 判断一个数是否是素数(质数)