面试被问到过滤器(Filter)和拦截器(Interceptor)的区别,支支吾吾说了个概念,并没有说出来两者的具体区别,所以就记录一下二者的区别。
过滤器(Filter)
- 过滤器其实就是一个servlet,用来实现拦截容器请求的servlet,是基于web容器的一种配置。
- 过滤器几乎可以拦截所有对web容器资源的请求
- 一般用来对请求统一处理,例如统一字符集,添加请求参数等,还有就是过滤掉一些非法的请求url
- 过滤器只在容器初始化时初始化一次,容器关闭时销毁
springboot中实现:
@WebFilter(filterName = "filter1", urlPatterns = "/web/user/*")
@Component
public class Filter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filter1 doFilter");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("filter1 destroy");
}
}
拦截器(Interceptor)
- 拦截器是spring基于aop实现的一种配置
- 拦截器只对web项目中的action(即controller)起作用,类似于对指定的controller配置切面进行处理
springboot中实现:
定义拦截器
public class Interceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("this is interceptor1 preHandle!");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("this is interceptor1 postHandle!");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("this is interceptor1 afterCompletion!");
}
}
注册拦截器
/**
* 注意这里要用实现WebMvcConfigurer的方式,不要使用继承WebMvcConfigurationSupport的方式
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 添加拦截器,配置拦截地址
// 配置的路径不需要context-path
// 多个拦截器的执行方式为先注册先执行,后置方法是先注册后执行
registry.addInterceptor(new Interceptor1()).addPathPatterns("/school/**");
}
}
两者的区别:
- filter依赖servlet(基于函数回掉),interceptor则是使用了aop(基于java反射)
- filter依赖web容器,interceptor是依赖spring
- filter可以过滤一切web请求,interceptor只对controller生效
- filter是在web容器初始化时初始化,interceptor时在ioc容器初始化时初始化(被注册的interceptor)
- 因为interceptor是基于spring,所以它可以访问ioc容器中的上下文,而filter不可以
一次request的流程(网上找的图来源:[https://www.imooc.com/article/266360]):
的流程.jpg){:height="50px" width="50px"}