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。
- public interface HandlerInterceptor {
- boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception;
- void postHandle(
- HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
- throws Exception;
- void afterCompletion(
- HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception;
- }
preHandle是调用Controller之前被调用,当返回false后,会跳过之后的拦截器,并且不会执行所有拦截器的postHandle,并调用返回true的拦截器的afterCompletion方法。
postHandle是调用Controller之后被调用,但是在渲染View页面之前。
afterCompletion是调用完Controller接口,渲染View页面最后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法,顺序相反。
和HandlerInterceptor很相似的要有一个AsyncHandlerInterceptor接口,只是多了个afterConcurrentHandlingStarted个方法,当接口使用了异步的方法的时候调用。
- public interface AsyncHandlerInterceptor extends HandlerInterceptor {
- void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception;
- }
2 HandlerInterceptor接口的定义
2.1 DispatcherServlet里doDispatch主处理逻辑
DispatcherServlet里doDispatch()就是springMVC的处理主要逻辑。因此肯定包含了拦截器的主要处理逻辑
- protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
- try {
- try {
- //.......省略代码
- //返回HandlerExecutionChain 其中包含了拦截器队列
- mappedHandler = getHandler(processedRequest);
- //调用拦截器PreHandle方法,若返回false不执行Controller逻辑,并不调用下面的PostHandle方法
- if (!mappedHandler.applyPreHandle(processedRequest, response)) {
- return;
- }
- // 处理Controller层
- mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
- applyDefaultViewName(processedRequest, mv);
- //调用拦截器的PostHandle方法
- mappedHandler.applyPostHandle(processedRequest, response, mv);
- }
- catch (Exception ex) {
- dispatchException = ex;
- }
- processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
- }
- catch (Exception ex) {
- //抛出异常后都会调用拦截器AfterCompletion方法
- triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
- }
- finally {
- if (asyncManager.isConcurrentHandlingStarted()) {
- // Instead of postHandle and afterCompletion
- if (mappedHandler != null) {
- //若Controller方法为异步调用,则执行拦截器afterConcurrentHandlingStarted(只有AsyncHandlerInterceptor拦截器才有)
- mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
- }
- }
- }
- }
2.2 获取拦截器
- protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
- //返回HandlerExecutionChain 其中包含了拦截器队列
- mappedHandler = getHandler(processedRequest);
- }
- //返回HandlerExecutionChain
- public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
- HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
- return executionChain;
- }
- protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
- HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
- (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
- //根据url和拦截器异常的配置url做对比,若符合则加入队列
- String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
- for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
- if (interceptor instanceof MappedInterceptor) {
- MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
- if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
- chain.addInterceptor(mappedInterceptor.getInterceptor());
- }
- }
- else {
- chain.addInterceptor(interceptor);
- }
- }
- return chain;
- }
- public boolean matches(String lookupPath, PathMatcher pathMatcher) {
- PathMatcher pathMatcherToUse = (this.pathMatcher != null) ? this.pathMatcher : pathMatcher;
- if (this.excludePatterns != null) {
- for (String pattern : this.excludePatterns) {
- if (pathMatcherToUse.match(pattern, lookupPath)) {
- return false;
- }
- }
- }
- if (this.includePatterns == null) {
- return true;
- }
- else {
- for (String pattern : this.includePatterns) {
- if (pathMatcherToUse.match(pattern, lookupPath)) {
- return true;
- }
- }
- return false;
- }
- }
上述的拦截器的信息,都来自与下面的配置文件
- <!-- 拦截器链 -->
- <mvc:interceptors>
- <mvc:interceptor>
- <!--拦截器mapping 符合的才会执行拦截器-->
- <mvc:mapping path="/**"/>
- <!--在拦截器mapping中除去下面的url -->
- <mvc:exclude-mapping path="/transactional_test/*"/>
- <!--执行的拦截器-->
- <ref bean="apiInterceptor"/>
- </mvc:interceptor>
- </mvc:interceptors>
- <bean id="apiInterceptor" class="com.lk.dome.interceptor.ApiInterceptor"/>
- ---------------------
2.3 处理拦截器
- boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
- HandlerInterceptor[] interceptors = getInterceptors();
- if (!ObjectUtils.isEmpty(interceptors)) {
- for (int i = 0; i < interceptors.length; i++) {
- HandlerInterceptor interceptor = interceptors[i];
- //若返回false,则直接执行拦截器的triggerAfterCompletion方法
- if (!interceptor.preHandle(request, response, this.handler)) {
- triggerAfterCompletion(request, response, null);
- //直接返回,在外层的doDispatch逻辑中不执行后面的逻辑
- return false;
- }
- //记录成功执行的拦截器个数
- this.interceptorIndex = i;
- }
- }
- return true;
- }
- void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
- HandlerInterceptor[] interceptors = getInterceptors();
- if (!ObjectUtils.isEmpty(interceptors)) {
- //拦截器队列从后往前之心,顺序相反
- for (int i = interceptors.length - 1; i >= 0; i--) {
- HandlerInterceptor interceptor = interceptors[i];
- interceptor.postHandle(request, response, this.handler, mv);
- }
- }
- }
- void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)
- throws Exception {
- HandlerInterceptor[] interceptors = getInterceptors();
- if (!ObjectUtils.isEmpty(interceptors)) {
- //interceptorIndex为执行成功的拦截器标志
- for (int i = this.interceptorIndex; i >= 0; i--) {
- HandlerInterceptor interceptor = interceptors[i];
- try {
- interceptor.afterCompletion(request, response, this.handler, ex);
- }
- catch (Throwable ex2) {
- logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
- }
- }
- }
- }
- //异步方法调用,拦截器必须属于AsyncHandlerInterceptor接口
- void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) {
- HandlerInterceptor[] interceptors = getInterceptors();
- if (!ObjectUtils.isEmpty(interceptors)) {
- for (int i = interceptors.length - 1; i >= 0; i--) {
- if (interceptors[i] instanceof AsyncHandlerInterceptor) {
- try {
- AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i];
- asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler);
- }
- catch (Throwable ex) {
- logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted", ex);
- }
- }
- }
- }
- }
springMVC之Interceptor拦截器的更多相关文章
- SpringMvc中Interceptor拦截器用法
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆等. 一. 使用场景 1 ...
- SpringMVC中使用Interceptor拦截器
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- SpringMVC 中的Interceptor 拦截器
1.配置拦截器 在springMVC.xml配置文件增加: <mvc:interceptors> <!-- 日志拦截器 --> <mvc:interceptor> ...
- SpringMVC中使用Interceptor拦截器顺序
一.简介 SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验 证,或者是来判断用户是否登陆,或者是像1 ...
- SpringMVC中的Interceptor拦截器及与Filter区别
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- springmvc中的拦截器interceptor用法
1.配置拦截器 在springMVC.xml配置文件增加: 1 <mvc:interceptors> 2 <!-- 日志拦截器 --> 3 <mvc:intercepto ...
- [转]SpringMVC中使用Interceptor拦截器
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- SpringMVC之七:SpringMVC中使用Interceptor拦截器
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- 9.springMVC中的拦截器
springMVC中的拦截器大概大致可以分为以下几个步骤去学习: 1.自定义一个类实现HandlerInterceptor接口,这里要了解其中几个方法的作用 2.在springMVC的配置文件中添加拦 ...
随机推荐
- WIFI_认证加密学习_STA_AP_WDS
2-1.1_15_使用卡1_准备工作及配置内核====================================1.无线网卡连接上路由或AP之后使用上是和有线网卡是一样的,都是socket编程. ...
- oracle 与sql serve 获取随机行数的数据
Oracle 随机获取N条数据 当我们获取数据时,可能会有这样的需求,即每次从表中获取数据时,是随机获取一定的记录,而不是每次都获取一样的数据,这时我们可以采取Oracle内部一些函数,来达到这 ...
- JS 网页快捷键设置
我们希望能用快捷键代替鼠标点击做一些事情,例如一个典型的应用就是论坛上常用的Ctrl + Enter 快捷发帖子.就以Ctrl+Enter快捷发帖子为例,实质上呢,就是通过JS脚本,捕获系统的onke ...
- 和为 s 的两个数字(和为 s 的连续正数序列)
题目 输入一个递增排序的数组和一个数字 s,在数组中查找两个数,得它们的和正好是 s.如果有多对数字的和等于 s,输出任意一对即可 思路 我们先在数组中选择两个数字,如果它们的和等于输入的 s,我们就 ...
- 浏览器的自动翻译会影响 JS 逻辑
有人在 QQ 群里反馈,官方注册后跳转时出现 Bug. 收到群友非常有用的资讯,这是因为浏览器的自动翻译功能引起的. 11:04:21[潜水]Better Command 2017/12/30 11: ...
- mac下hbase安装
出处:https://www.jianshu.com/p/510e1d599123 安装到的路径:/usr/local/Cellar/hbase/1.2.6 linux操作: linux命令 作用 . ...
- POJ1179 Polygon
题目:http://poj.org/problem?id=1179 石子合并的升级版.有负值.但运算符只有 + 和 * . 考虑负值对原做法正确性的影响:之所以仅记录最大值可能不对,是因为有可能负数 ...
- 二、Jmeter录制脚本过程及Could not create script recorder报错、您的连接不是私密连接报错
两个报错:Could not create script recorder报错和您的连接不是私密连接报错 1.录制过程 * 打开jmeter * 点击Templated,选择Recoding模版 * ...
- ORA-01919: role 'OLAPI_TRACE_USER' does not exist
我在用数据泵导入数据的时候报的错 TEST_USER1@ORCL> conn / as sysdbaSYS@ORCL> grant plustrace to TEST_USER1; gra ...
- 什么是JavaBean、bean? 什么是POJO、PO、DTO、VO、BO ? 什么是EJB、EntityBean?
什么是JavaBean.bean? 什么是POJO.PO.DTO.VO.BO ? 什么是EJB.EntityBean? 前言: 在Java开发中经常遇到这些概念问题,有的可能理解混淆,有的 ...