SpringBoot 使用 过滤器、拦截器、监听器
SpringBoot 使用 过滤器、拦截器、监听器
参考链接
https://javabetter.cn/springboot/Filter-Interceptor-Listener.html
https://segmentfault.com/a/1190000037755221
https://blog.csdn.net/xinzhifu1/article/details/106356958
https://segmentfault.com/a/1190000013240470#item-1
![image](/assets/view-BfpLryKP.png)
![image](/assets/9e55a422-e676-4a8d-b999-a720415f81ee-1722585826602-4-BTvLMfJ3.png)
过滤器 依赖于 Servlet 容器
拦截器依赖于 Spring 的 IoC容器(因此可以通过注入方式获取容器中的对象)
监听器 用于监听Web应用中某些对象的创建销毁、增加、修改、删除等动作并作出相应的处理
过滤器(Filter):过滤符合预期的请求
拦截器(Interceptor):干涉请求?
监听器(Listener):监听请求具体做了什么?
过滤器
作用
- 过滤敏感词汇(防止SQL注入?
- 设置字符编码
- URL级别的权限访问控制
- 压缩响应信息
过滤器链 FilterChain
xxxFilter(自定义过滤器)s先执行自身 doFilter()过滤逻辑,最后执行filterChain.doFilter(servletRequest, servletResponse),回调ApplicationFilterChain的doFilter()方法,以此循环执行 实现 函数回调
![在这里插入图片描述](/assets/384ba0d4e5c73e5670194ea97fab2725-X0G2fE1a.png)
自定义过滤器
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//do something...
filterChain.doFilter(servletRequest, servletResponse);
}
ApplicationFilterChain
public final class ApplicationFilterChain implements FilterChain {
@Override
public void doFilter(ServletRequest request, ServletResponse response) {
...//省略
internalDoFilter(request,response);
}
private void internalDoFilter(ServletRequest request, ServletResponse response){
if (pos < n) {
//获取第pos个filter
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = filterConfig.getFilter();
...
filter.doFilter(request, response, this);
}
}
}
FilterChain
public interface FilterChain {
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}
过滤器的使用
SpringBoot提供的FilterRegistrationBean注册Filter
自定义Filter implements
Filter
public class MyFilter implements Filter {
@override
public void init(){}
@override
pubic void doFilter(){}
@override
public void destroy(){}
}
使用SpringBoot提供的FilterRegistrationBean注册Filter
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registFilter() {
FilterRegistrationBean registation = new FilterRegistationBean();
registation.setFilter(new MyFilter());
registration.addUrlPatterns("/*");
registration.setName("LogCostFilter");
registration.setOrder(1);
return registration;
}
}
使用原生Servlet注解定义Filter
启动类 添加注解 @ServletComponentScan
定义扫描的包
自定义Filter
@Component
//filterName,过滤的url
@WebFilter(filterName = "xxx", urlPatterns = "/*")
public class MyFilter implements Filter {
@override
public void init(){}
@override
pubic void doFilter(){}
@override
public void destroy(){}
}
拦截器
作用
- 登陆验证
- 权限验证(如校验token
- 日志记录(记录请求的用户IP、访问时间
- 处理cookie、本地化、国际化、主题等
- 性能监控,监控请求处理时长等
拦截器 本质上是面向切面编程(AOP)
拦截器的使用
自定义拦截器
public class MyInterceptor implements HandlerInterceptor {
//Controller 方法调用前执行
@Override
public bolean preHandle(){}
//postHandler是请求结束执行,只有preHandle方法返回true的时候才会执行
@Override
public void postHandle() {}
//视图渲染完成后才执行,同样需要preHandle返回true,该方法通常用于清理资源等工作
@Override
public void afterCompletion() {}
}
注册拦截器
@Configuration
public class InterceptorConfig extends WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}
执行流程
Filter->Interceptor.preHandle->Handler->Interceptor.postHandle->Interceptor.afterCompletion->Filter
过滤器的实现 基于 回调 函数,拦截器(代理模式?)的实现 基于 反射?
![image.png](/assets/bVcIzUy-SDglbaF8.png)
监听器
监听器的组件
事件源,事件对象,事件监听器
![这里写图片描述](/assets/1460000013240473-B9_0NPz-.png)
Servlet中,监听器的监听对象(事件源)可以分为
ServletContext,HttpSession,ServletRequest
监听对象的创建和销毁
ServletRequestListener
监听Context对象的创建和销毁
可以获取web.xml里面的参数配置
HttpSessionListener
监听 Session(会话) 对象的创建和销毁
可以用来收集在线者信息
ServletRequestListener
监听 Request(封装请求数据)对象的创建和销毁
监听对象属性变化
ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener
监听Session内的对象
HttpSessionBindingListener
HttpSessionActivationListener
自定义Listener
//使用注解代替web.xml
@WebListener
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("上下文创建");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("上下文销毁");
}
}
//ServletContextListener 能够监听整个 Web 应用程序的生命周期。当 Web 应用启动时触发 contextInitialized 方法,关闭时触发 contextDestroyed 方法