天天看点

过滤器Filter和拦截器Interceptor的区别及其使用

作者:王朋code

过滤器:依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。类似公路上的收费站

拦截器:是基于Java的jdk动态代实现的,实现HandlerInterceptor接口。不依赖于servlet容器, 拦截器针对于controller方法,并且能获取到所有的类,对类里面所有的方法实现拦截,粒度更小,拦截器中可以注入service,也可以调用业务逻辑

拦截器和过滤器对比:

  • 两者都是AOP编程思想的实现,都能够实现权限控制和日志记录等问题的处理,但是两者粒度不同拦截对象不一样
  • 适用范围不同:Filter是servlet的规范,只能用于web程序,但是拦截器是spring的,它位于org.springframework.web.servlet.handler包下,可以用于application等程序。
  • 规范不同:Filter是servlet的规范。但是Interceptor是spring容器支撑,有spring框架支持。
  • 使用资源不一样:spring的拦截器由于依赖spring,也是spring的一个组件,因此能够在拦截器中使用spring的任何资源和对象。例如service对象,数据源,事务管理等,通过ioc注入拦截器即可,而filter不能
  • 粒度不同:Filter只能在servlet的前后起作用,而拦截器能在方法前后异常前后执行,更加灵活,粒度更小,spring框架程序优先使用拦截器。

过滤器的两种方式使用:

@WebFilter(urlPatterns = "/*")
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebRqsTypeChangeFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //将ServletRequest封装一下,因为request.getInputStream()方法只能读取一次,所以不能和@requestBody一起使用
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);
        chain.doFilter(requestWrapper, response);
    }

}
然后在main方法上使用@ServletComponentScan注解即可           
//在配置类中加入
@Bean
public FilterRegistrationBean<GenericFilterBean> WebRqsTypeChangeFilter(){
    FilterRegistrationBean<GenericFilterBean> registration = new FilterRegistrationBean<>();
    registration.setFilter(new WebRqsTypeChangeFilter());
    registration.addUrlPatterns("/*");
    registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return registration;
}           

拦截器的使用:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //这个感觉没啥用,优先级放到最高,这样下面的拦截器可以将其覆盖
        registry.addInterceptor(new TrcInterceptor()).order(Ordered.HIGHEST_PRECEDENCE);
        //这个是我们自己的,将他的优先级放到最低
        registry.addInterceptor(new WebRqsTypeChangeInterceptor()).order(Ordered.LOWEST_PRECEDENCE);
        log.info("TrcInterceptor、WebRqsTypeChangeInterceptor register done");
    }

}           
//在配置类中
@Bean
public FilterRegistrationBean<GenericFilterBean> trcFilter() {
    FilterRegistrationBean<GenericFilterBean> registration = new FilterRegistrationBean<>();
    registration.setFilter(new TrcFilter());
    registration.addUrlPatterns("/*");
    registration.setOrder(1);
    return registration;
}           
过滤器Filter和拦截器Interceptor的区别及其使用

继续阅读