spring boot学习---过滤器 监听器 拦截器
目录
- 应用场景
- 环境准备
- 过滤器
- 监听器
- 拦截器
- 链路说明
- 运行结果
- 过滤器和拦截器比较
1. 应用场景
在开发过程中,经常碰到系统启动的数据初始化、统计在线人数、权限校验、日志记录等业务需求。这些操作和具体业务没有关联,都是系统层面的功能,这些功能的实现可能就是会用到过滤器、监听器、拦截器这些功能
2. 环境准备
2.1 引入jar包
compile('org.projectlombok:lombok:1.18.2')
implementation('org.springframework.boot:spring-boot-starter-web')
2.2 新建一个controller类
@RestController
@Slf4j
public class TestController {
@GetMapping(value = "hello")
public String hello() {
log.info("具体执行方法:hello");
return "hello";
}
}
3. 过滤器
3.1 说明:
过滤器Filter,是Servlet的的一个实用技术了。可通过过滤器,对请求进行拦截,比如读取session判断用户是否登录、判断访问的请求URL是否有访问权限(黑白名单)等。
3.2 spring boot中实现
一、实现Filter
@WebFilter(filterName="MyFilter",urlPatterns={"/*"})
@Order(value = 1)
@Slf4j
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("过滤器 初始化");
}
@Override
public void destroy() {
log.info("过滤器 初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("过滤器 开始调用方法");
//链路 直接传给下一个过滤器
chain.doFilter(request, response);
log.info("过滤器 方法调用完成");
}
}
二、启动类添加@ServletComponentScan注解
三、保证Filter有序性
流程: 启动类添加方法,去掉ServletComponentScan注解,通过setOrder值设置执行顺序,多个时注册多个bean
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registration = new FilterRegistrationBean();
//当过滤器有注入其他bean类时,可直接通过@bean的方式进行实体类过滤器,这样不可自动注入过滤器使用的其他bean类。
//当然,若无其他bean需要获取时,可直接new createMyFilter(),也可使用getBean的方式。
registration.setFilter(createMyFilter());
//过滤器名称
registration.setName("createMyFilter");
//拦截路径
registration.addUrlPatterns("/*");
//设置顺序
registration.setOrder(10);
return registration;
}
@Bean
public Filter createMyFilter() {
return new MyFilter();
}
4. 监听器
4.1 说明
Lister是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件
4.2 spring boot实现
一、添加监听器
@WebListener
@Slf4j
public class MyLister implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
log.info("监听器:销毁");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
log.info("监听器:初始化");
}
}
二 启动类添加@ServletComponentScan注解
5. 拦截器
5.1 说明:
以上的过滤器、监听器都属于Servlet的api,我们在开发中处理利用以上的进行过滤web请求时,还可以使用Spring提供的拦截器(HandlerInterceptor)进行更加精细的控制
5.2 spring boot的实现
一、创建拦截器
@Slf4j
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
log.info("拦截器:请求前调用");
//返回 false 则请求中断
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info("拦截器:请求后调用");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.info("拦截器:请求调用完成后回调方法,即在视图渲染完成后回调");
}
}
二、注册拦截器
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册拦截器 拦截规则
//多个拦截器时 以此添加 执行顺序按添加顺序
registry.addInterceptor(getHandlerInterceptor()).addPathPatterns("/*");
}
@Bean
public static HandlerInterceptor getHandlerInterceptor() {
return new MyHandlerInterceptor();
}
}
6 链路说明
6.1包含图
6.2链路图
7 添加监听器、过滤器、拦截器三个后运行结果
监听器:初始化
Initializing Spring DispatcherServlet 'dispatcherServlet'
Initializing Servlet 'dispatcherServlet'
Completed initialization in 5 ms
过滤器 开始调用方法
拦截器:请求前调用
具体执行方法:hello
拦截器:请求后调用
拦截器:请求调用完成后回调方法,即在视图渲染完成后回调
过滤器 方法调用完成
监听器:销毁
8 过滤器和拦截器比较
应用场景 | 拦截器 | 过滤器 |
---|---|---|
适用范围 | 既可以用于web程序,又可以用于application、swing程序 | 是servlet规范,只能用于web程序中 |
规范 | 是在spring容器内,是spring框架支持的 | 是Servlet规范中定义的,是servlet容器支持的 |
使用的资源 | 能使用spring里的任何资源对象,例如servie对象、数据源、事务管理等、通过IOC注入到拦截器即可 | 不支持 |
深度 | 能够深入到方法前后、异常、抛出前后等,因此拦截器使用具有更大的弹性因此在spring框架中要优先使用拦截器 | 只在Servlet前后起作用 |