目录
- Spring Boot 过滤器
- 1.什么是过滤器
- 2.工作机制
- 3.实现过滤器
- Spring Boot 拦截器
- 1. 什么是拦截器
- 2. 工作原理
- 3.实现
- 4.拓展(MethodInterceptor 拦截器)
- 实现
- 过滤器和拦截器区别
- 过滤器和拦截器应用场景
- 过滤器
- 拦截器
Spring Boot 过滤器
1.什么是过滤器
-
过滤器(Filter),是 Servlet 规范规定的,在 Servlet 前执行的。用于拦截和处理 HTTP 请求和响应,可用于身份认证、授权、日志记录和设置字符集(CharacterEncodingFilter)等场景。
-
过滤器位于整个请求处理流程的最前端,因此在请求到达 Controller 层前,都会先被过滤器处理。
-
过滤器可以拦截多个请求或响应,一个请求或响应也可以被多个过滤器拦截。
2.工作机制
Filter 的生命周期对应的三个关键方法:
方法 | 作用 |
---|---|
init() | 当请求发起是,会调用init()方法初始化Filter实例,仅初始化一次 ,若设置初始化参数时可调用该方法 |
doFilter() | 拦截要执行的请求,对请求和响应进行处理 |
destroy() | 请求结束时调用该方法销毁Filter的实例 |
3.实现过滤器
- 实现 Filter 接口
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 用于完成 Filter 的初始化
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("过滤器已经拦截成功!!!");
// 执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。
chain.doFilter(request,response);
}
@Override
public void destroy() {
// 用于 Filter 销毁前,完成某些资源的回收;
Filter.super.destroy();
}
}
- 启动类添加注解 @ServletComponentScan
- 通过@Component和@Order(1)注解可以保证过滤器执行顺序
Spring Boot 拦截器
1. 什么是拦截器
依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
2. 工作原理
SpringMVC的机制是由同一个Servlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。所以过滤器、拦截器、service()方法,dispatc()方法的执行顺序应该是这样的
3.实现
配置拦截器,实现WebMvcConfigurer接口,加@Configuration注解并重写addInterceptors方法。
@Configuration
public class MyWebConfigurer implements WebMvcConfigurer {
@Resource
private MyHandlerInterceptor myHandlerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
List<String> patterns = new ArrayList<>();
patterns.add("/test/handlerInterceptor");
registry.addInterceptor(myHandlerInterceptor)
.addPathPatterns(patterns) // 需要拦截的请求
.excludePathPatterns(); // 不需要拦截的请求
}
}
4.拓展(MethodInterceptor 拦截器)
-
MethodInterceptor 是 AOP 中的拦截器,它拦截的目标是方法,可以不是 Controller 中的方法。
-
在对一些普通的方法上的拦截可以使用该拦截器,这是 HandlerInterceptor 无法实现的。
-
可用来进行方法级别的身份认证、授权以及日志记录等,也可基于自定义注解实现一些通用的方法增强功能。
实现
MethodInterceptor 是基于 AOP 实现的,所以根据不同的代理有多种实现方式。
- 创建 Interceptor 类,实现MethodInterceptor接口,重写invoke方法,加@Component注解。
@Component
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("进入拦截,方法执行前,拦截方法是:" + invocation.getMethod().getName());
Object result = invocation.proceed();
System.out.println("方法执行后");
return result;
}
}
- 配置自动代理,加@Configuration注解并创建自动代理BeanNameAutoProxyCreator。
@Configuration
public class MyMethodConfigurer {
@Resource
private MyMethodInterceptor myMethodInterceptor;
@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
// 使用BeanNameAutoProxyCreator来创建代理
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
// 指定一组需要自动代理的Bean名称,Bean名称可以使用*通配符
beanNameAutoProxyCreator.setBeanNames("user*");
//设置拦截器名称,这些拦截器是有先后顺序的
beanNameAutoProxyCreator.setInterceptorNames("myMethodInterceptor");
return beanNameAutoProxyCreator;
}
}
过滤器和拦截器区别
-
过滤器是基于函数回调,拦截器是基于java的反射机制的。
-
过滤器是servlet规范规定的,只能用于web程序中,而拦截器是在spring容器中,它不依赖servlet容器。
-
过滤器可以拦截几乎所有的请求(包含对静态资源的请求),而拦截器只拦截action请求(不拦截静态资源请求)。
-
过滤器不能访问action上下文、值栈里的对象,拦截器可以访问action上下文、值栈里的对象。
-
在action的生命周期中,过滤器只能在容器初始化时被调用一次,拦截器可以多次被调用,而。
-
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
-
拦截器是被包裹在过滤器之中。
过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。
拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。
切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和响应的对象
过滤器和拦截器应用场景
过滤器
- 过滤敏感词汇(防止sql注入)
- 设置字符编码
- URL级别的权限访问控制
- 压缩响应信息
拦截器
- 登录验证,判断用户是否登录。
- 权限验证,判断用户是否有权限访问资源,如校验token
- 日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
- 处理cookie、本地化、国际化、主题等。
- 性能监控,监控请求处理时长等。
- 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现)