框架给我们的开发带来很多便利的地方,而许多从前学习到的一些知识的使用,在框架中会稍有不同,该文章主要对过滤器和拦截器在框架中的使用进行描述,并分析过滤器、拦截器和AOP的关系及区别
过滤器
过滤器的作用主要是对路径匹配的请求进行拦截,然后对请求进行相应处理后,再将请求放行去执行原来的处理逻辑。
当有多个过滤器时,会形成一个过滤器链,会逐一执行,只有在请求路径匹配时,才会被过滤器拦截
使用
创建一个类,实现Filter接口,并重写doFilter()方法
@Slf4j
public class TimeFilter implements Filter {
private SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:S");
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("TimeFilter拦截的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
chain.doFilter(request, response);
log.info("执行完请求处理逻辑后,回到TimeFilter的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
}
}
创建配置类,利用方法创建过滤器并放入容器中
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean TimeFilter(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
TimeFilter timeFilter = new TimeFilter();
filterRegistrationBean.setFilter(timeFilter);
// 添加拦截路径
filterRegistrationBean.addUrlPatterns("/filter/*");
Set<String> path = new HashSet<>();
// 多路径情况
// path.add("/filter/test1");
// path.add("/filter/test2");
// filterRegistrationBean.setUrlPatterns(path);
// 设置过滤器的执行顺序
filterRegistrationBean.setOrder(1);
return filterRegistrationBean;
}
}
测试
请求接口并查看日志信息
在日志信息可以看到,请求成功被过滤器拦截
拦截器
拦截器也是根据请求路径来进行拦截的,拦截器类似于Aop,都是使用代理模式实现的,它可对你所需访问的接口方法的执行前后进行操作。在框架中,可以通过实现HandlerInterceptor接口来创建拦截器,需重写preHandle()、postHandle()、afterCompletion()三个方法。
使用
创建一个类,实现HandlerInterceptor接口并重写preHandle()、postHandle()、afterCompletion()方法
@Slf4j
@Component
public class TimeInterceptor implements HandlerInterceptor {
private SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:S");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("调用TimeInterceptor中的preHandle()方法的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
// 只有返回值为true时,才能够继续执行postHandle()、afterCompletion()方法,若是false表示请求结束,将会不再执行
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("调用TimeInterceptor中的postHandle()方法的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("调用TimeInterceptor中的afterCompletion()方法的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
}
}
在配置类中,把拦截器添加到容器中,并设置拦截路径
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private TimeInterceptor timeInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timeInterceptor).addPathPatterns("/interceptor/*");
// 多路径配置
// List<String> path = new ArrayList<>();
// path.add("/interceptor/test1");
// path.add("/interceptor/test2");
// registry.addInterceptor(timeInterceptor).addPathPatterns(path);
}
}
测试
请求接口并查看日志信息
在日志中可以看到,拦截器已经成功拦截到了请求,并执行了三个方法
过滤器、拦截器、Aop
执行顺序
当过滤器、拦截器、Aop都用于一个请求路径的接口方法时,执行顺序为 过滤器-》拦截器-》AOP
作用
过滤器的主要作用
- 用户访问权限处理
- 设置字符集乱码处理
- 过滤敏感词汇、压缩响应信息
拦截器的主要作用
- 只能拦截请求,可以访问上下文等对象,功能强大,一个请求可多次拦截。
- 用户访问权限处理
- 登记日志
AOP的主要作用
- 日志记录
- 性能统计
- 安全控制
- 事务处理
- 异常处理
- 只能应用于由 Spring 容器管理的 bean
一般情况下,数据被过滤拦截的时机越早对服务的性能影响越小,在编写相对比较公用的代码时,优先考虑过滤器,然后是拦截器,最后是AOP
区别
- 过滤器与拦截器的拦截是通过匹配请求路径实现的,而AOP(面向切面)拦截可以通过切点切向包、类、方法名、参数等
- Spring AOP和拦截器一样,都是AOP的实现方式的一种,均使用代理模式实现
- Aop能够对包、类、方法名、参数等拦截,相对于拦截其而言,更加灵活,Aop可以针对具体的代码,去实现更加复杂的业务逻辑
- 拦截器只对action负责,作用层面一般位于Controller层,Spring AOP主要是拦截对Spring管理的Bean的访问,一般作用与Service层