过滤器和拦截器的区别

简介: Filter 也称为过滤器,基于Servlet实现,拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行,基于AOP思想,对方法进行增强。和servlet 中的过滤器类似,都是对用户请求进行处理。

什么是过滤器?


Filter 也称为过滤器,基于Servlet实现,过滤器的主要应用场景是对字符编码、跨域等问题进行过滤。Servlet的工作原理是拦截配置好的客户端请求,然后对Request和Response进行处理。Filter过滤器随着web应用的启动而启动,只初始化一次。


什么是拦截器?


拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行,基于AOP思想,对方法进行增强。和servlet 中的过滤器类似,都是对用户请求进行处理。



他们有什么不同?


  1. 拦截器是基于Java的反射机制,而过滤器是基于函数回调;
  2. 拦截器不依赖servlet容器,过滤器依赖servlet容器;
  3. 拦截器只能对Controller 请求起作用,而过滤器则可以对几乎所有的请求起作用;
  4. 拦截器可以访问action上下文、堆栈里的对象,过滤器不能访问;
  5. 在action生命周期中,拦截器可以多次被调用,过滤器只能在容器初始化时被调用一次。


在springboot中使用拦截器和过滤器


使用过滤器,有两种方式


  1. 实现 Filter 类,重写其 doFilter 方法,注意这个类是 javax.servlet 包下的


@Slf4j
@Component
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        log.info("进入过滤器 MyFilter");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
  1. 注册


@Configuration
public class FilterConfig {
    @Autowired
    private MyFilter myFilter;
    @Bean
    public FilterRegistrationBean injectFilterOne() {
        FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(myFilter);
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("filter_one");
        // 优先级
        registrationBean.setOrder(1);
        return registrationBean;
    }
}
  1. 使用 @WebFilter 注解


@Slf4j
@WebFilter(filterName = "filter_two", urlPatterns = {"/*"})
public class MyFilter2 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        log.info("进入过滤器 MyFilter2");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
  1. 这种方式需要在启动类上扫描 @WebFilter注解,需要加上以下注解
    @ServletComponentScan(value = {"com.example.config.filter"})


使用拦截器


新建一个类实现 HandlerInterceptor 接口



@Component
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("进入拦截器 MyIntercept,preHandle 方法 ");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("进入拦截器 MyIntercept,postHandle 方法 ");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("进入拦截器 MyIntercept,afterCompletion 方法 ");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

注册


@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 拦截器拦截路径
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }
}


1. preHandle(......)方法:当url已经匹配到controller层中某个方法时,在方法执行前执行
它会决定是否放行,返回true,放行,返回false,不会执行
2.  postHandle(……) 方法:url 匹配到Controller 中的某个方法,且执行完了该方法,
但是在 DispatcherServlet 视图渲染之前执行。在这个方法中有个 ModelAndView 参数,可以在此做一些修改动作。
3. afterCompletion(……) 方法:在整个请求处理完成后(包括视图渲染)执行,
做一些资源的清理工作,这个方法只有在 preHandle(……) 被成功执行后并且返回true才会被执行。


过滤器和拦截器放在一起的执行结果:



2023-05-06 23:41:48.774  INFO 15484 --- [nio-8080-exec-2] com.example.config.filter.MyFilter       : 进入过滤器 MyFilter
2023-05-06 23:41:48.774  INFO 15484 --- [nio-8080-exec-2] com.example.config.filter.MyFilter2      : 进入过滤器 MyFilter2
2023-05-06 23:41:48.785  INFO 15484 --- [nio-8080-exec-2] c.e.config.interceptor.MyInterceptor     : 进入拦截器 MyIntercept,preHandle 方法 
2023-05-06 23:41:48.807  INFO 15484 --- [nio-8080-exec-2] c.e.config.interceptor.MyInterceptor     : 进入拦截器 MyIntercept,postHandle 方法 
2023-05-06 23:41:48.807  INFO 15484 --- [nio-8080-exec-2] c.e.config.interceptor.MyInterceptor     : 进入拦截器 MyIntercept,afterCompletion 方法


参考文章


  1. blog.csdn.net/K_520_W/art…
  2. www.cnblogs.com/wangms821/p…
目录
相关文章
|
4月前
|
Java 应用服务中间件 数据安全/隐私保护
面试官:过滤器Filter和拦截器Interceptors有什么区别?
面试官:过滤器Filter和拦截器Interceptors有什么区别?
32 0
|
3月前
过滤器&拦截器
过滤器&拦截器
32 0
过滤器&拦截器
|
4月前
SpringMVC-拦截器参数及拦截器链配置
SpringMVC-拦截器参数及拦截器链配置
32 0
|
Java 应用服务中间件 API
过滤器和拦截器
过滤器和拦截器
140 0
|
XML Java 关系型数据库
过滤器和拦截器的区别
过滤器和拦截器的区别
86 0
|
JSON 运维 数据格式
[SpringMVC]拦截器②(拦截器参数、拦截器链配置)
拦截器②(拦截器参数、拦截器链配置)
[SpringMVC]拦截器②(拦截器参数、拦截器链配置)
SpringMVC:拦截器和过滤器的区别
SpringMVC:拦截器和过滤器的区别
103 0
SpringMVC:拦截器和过滤器的区别
|
Java 容器
SpringMVC:过滤器和拦截器的区别和实现原理
SpringMVC:过滤器和拦截器的区别和实现原理
SpringMVC:过滤器和拦截器的区别和实现原理
Struts2拦截器的简单应用,登录权限拦截器及与过滤器的区别(八)上
Struts2拦截器的简单应用,登录权限拦截器及与过滤器的区别(八)
132 0
Struts2拦截器的简单应用,登录权限拦截器及与过滤器的区别(八)上
|
Java 数据安全/隐私保护 容器
Struts2拦截器的简单应用,登录权限拦截器及与过滤器的区别(八)下
Struts2拦截器的简单应用,登录权限拦截器及与过滤器的区别(八)
145 0
Struts2拦截器的简单应用,登录权限拦截器及与过滤器的区别(八)下