SpringBoot之HandlerInterceptorAdapter
SpringBoot之HandlerInterceptorAdapter
在SpringBoot中我们可以使用HandlerInterceptorAdapter这个适配器来实现自己的拦截器。这样就可以拦截所有的请求并做相应的处理。
应用场景
- 日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。
- 权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。
- 性能监控:典型的是慢日志。
在HandlerInterceptorAdapter中主要提供了以下的方法:
preHandle:在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行,也就是说我们想调用的方法 不会被执行,但是你可以修改response为你想要的响应。
postHandle:在方法执行后调用。
afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。
在HandlerInterceptorAdapter中主要提供了以下的方法:
- preHandle:在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行,也就是说我们想调用的方法 不会被执行,但是你可以修改response为你想要的响应。
- postHandle:在方法执行后调用。
- afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。
HandlerInterceptor
拦截器适配器HandlerInterceptorAdapter
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
/**
* This implementation always returns {@code true}.
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
}
}
有时候我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor接口的话,三个方法必须实现,不管你需不需要,此时spring提供了一个HandlerInterceptorAdapter适配器(种适配器设计模式的实现),允许我们只实现需要的回调方法。
这样在我们业务中比如要记录系统日志,日志肯定是在afterCompletion之后记录的,否则中途失败了,也记录了,那就扯淡了。一定是程序正常跑完后,我们记录下那些对数据库做个增删改的操作日志进数据库。所以我们只需要继承HandlerInterceptorAdapter,并重写afterCompletion一个方法即可,因为preHandle默认是true。
运行流程总结如下:
- 拦截器执行顺序是按照Spring配置文件中定义的顺序而定的。
- 会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。
- 然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。
- 在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后,执行after进行清理工作)方法。(postHandle和afterCompletion都是倒序执行)
下面用一个demo来演示执行流程
定义一个类继承HandlerInterceptorAdapter,并重写方法
快捷键ctrl+o打开可以重写的方法面板选择
package com.example.demo.config;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.err.println("================================== preHandle1 ===========================================");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.err.println("================================== postHandle1 ===========================================");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.err.println("================================== afterCompletion1 ===========================================");
}
}
WebMvcConfigurerAdapter 抽象类是对WebMvcConfigurer接口的简单抽象(增加了一些默认实现),但在在SpringBoot2.0及Spring5.0中WebMvcConfigurerAdapter已被废弃 。官方推荐直接实现WebMvcConfigurer或者直接继承WebMvcConfigurationSupport
实现WebMvcConfigurer配置拦截器
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor());
}
}
在控制器中写一个方法并访问
@ApiOperation(value = "test mybatis", notes = "")
@RequestMapping(value = "getuser", method = RequestMethod.GET)
public User getUser() {
return userService.getUser();
}
会在控制台输出
此时在加入一个拦截器,会按照配置的顺序执行,配置如下
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor());
registry.addInterceptor(new LogInterceptor2());
}
}
控制的输出反映了配置多个拦截器的执行流程:
如果controller出现异常,则不会继续执行postHandle,只会倒序执行afterCompletion方法
转载地址:https://www.cnblogs.com/weianlai/p/11358768.html
SpringBoot之HandlerInterceptorAdapter的更多相关文章
- Springboot 拦截器(HandlerInterceptorAdapter)中注入无效
1,传统filter和HandlerInterceptorAdapter的区别 springboot对传统Filter进行增强,添加更多细粒度的操作,分别实现预处理.后处理(调用了Service并返回 ...
- Grafana+Prometheus系统监控之SpringBoot
前言 前一段时间使用SpringBoot创建了一个webhook项目,由于近期项目中也使用了不少SpringBoot相关的项目,趁着周末,配置一下使用prometheus监控微服务Springboot ...
- 基于springboot搭建的web系统架构
从接触springboot开始,便深深的被它的简洁性深深的折服了,精简的配置,方便的集成,使我再也不想用传统的ssm框架来搭建项目,一大堆的配置文件,维护起来很不方便,集成的时候也要费力不少.从第一次 ...
- 带着萌新看springboot源码05
上一节走了一遍从浏览器发出请求到得到向页面的流程,基本的功能是已经实现了.但是现在啊,我想自定义一个拦截器(拦截器可以做用户登录验证,如果登录了,就让你通过,如果没有登录,就重定向登录页面),这里就不 ...
- SpringBoot webmvc项目导出war包并在外部tomcat运行产生的诸多问题以及解决方案
背景: 有需求要将原来的Spring(3.2.6) + Springmvc + Hibernate项目重构为Springboot(1.5.2)项目 描述: 记录重构过程,以及期间遇到的种种问题和对应的 ...
- spring 或 springboot统一异常处理
spring 或 springboot统一异常处理https://blog.csdn.net/xzmeasy/article/details/76150370 一,本文介绍spring MVC的自定义 ...
- 配置springboot在访问404时自定义返回结果以及统一异常处理
在搭建项目框架的时候用的是springboot,想统一处理异常,但是发现404的错误总是捕捉不到,总是返回的是springBoot自带的错误结果信息. 如下是springBoot自带的错误结果信息: ...
- Springboot中SpringMvc拦截器配置与应用(实战)
一.什么是拦截器,及其作用 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对 ...
- 精通SpringBoot:详解WebMvcConfigurer接口
SpringBoot 确实为我们做了很多事情, 但有时候我们想要自己定义一些Handler,Interceptor,ViewResolver,MessageConverter,该怎么做呢.在Sprin ...
随机推荐
- mysql查看数据库大小
要想知道每个数据库的大小的话,步骤如下: 1.进入information_schema 数据库(存放了其他的数据库的信息) use information_schema; 2.查询所有数据的大小: s ...
- robot_framewok自动化测试--(2)创建第一个项目
创建第一个robot_framewok项目 通过 RIDE 去学习和使用 Robot Framework 框架,对于初学者来说大大的降低了学习难度.所以后面对 Robot Framework 框架都将 ...
- Java测试开发--Comparable和Comparator接口(五)
Comparable 简介Comparable 是排序接口.若一个类实现了Comparable接口,就意味着"该类支持排序".此外,"实现Comparable接口的类的对 ...
- Beyond compare 4.2.3 激活和秘钥
安装完 Beyond Compare 4.2.3 以后.打开输入密匙是不是会跳到官网去?不用慌,我们只需要删除你安装Beyond Compare 4目录下的 BCUnrar.dll 文件,然后再打开就 ...
- Python基础(filter)
arr = [1,2,3,1,1,3,6,9] def f1(x): if x > 2: return True arr1 = list(filter(f1,arr)) print(arr1)# ...
- Chrome handless无界面浏览器的脚本操作
1.什么是Phantomjs (已经停止更新) 是一个无界面的浏览器 支持页面元素查找,js的执行等 由于不进行css和gui渲染,运行效率要比真实的浏览器要快很多 2.如何使用Phantomjs? ...
- python接口之request测试:以json格式发送post请求,.json方法,查看响应结果的情况
json和dict python中的dict类型要转换为json格式的数据需要用到json库: import json <json> = json.dumps(<dict>) ...
- springboot默认Thymeleaf模板引擎js的解决方案
<script th:inline="javascript"> var btnexam=[[${btnexam}]]; console.log(btnexam); va ...
- MySQL的B+树索引和hash索引的区别
简述一下索引: 索引是数据库表中一列或多列的值进行排序的一种数据结构:索引分为聚集索引和非聚集索引,聚集索引查询类似书的目录,快速定位查找的数据,非聚集索引查询一般需要再次回表查询一次,如果不使用索引 ...
- 浅谈java中的四个核心概念--思途青岛
Java已经成为一个庞大而复杂的技术平台,对于开发人员而言,要想更好的掌握Java技术,深入理解底层的技术处理细节必不可少. 现在介绍下java的四个核心概念: 1.Java虚拟机 Java虚拟机的主 ...