Java web / 其他 · 2019年5月24日 0

Spring Boot 过滤器和拦截器总结

![请输入图片描述][1]### 拦截器与过滤器的区别

过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。

SpringMVC的机制是由DispaterServlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的.

过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射,代理分静态代理和动态代理,动态代理是拦截器的简单实现。

过滤器就是过滤的作用,在web开发中过滤一些我们指定的url
那么它能帮我们过滤什么呢?
那功能可就多了:
比如过拦截掉我们不需要的接口请求
修改请求(request)和响应(response)内容
完成CORS跨域请求等等

最简单明了的区别就是 过滤器可以修改request,而拦截器不能过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境拦截器可以调用IOC容器中的各种依赖,而过滤器不能过滤器只能在请求的前后使用,而拦截器可以详细到每个方法

过滤器就是筛选出你要的东西,比如requeset中你要的那部分
拦截器在做安全方面用的比较多,比如终止一些流程

何时使用拦截器?何时使用过滤器?

  • 如果是非spring项目,那么拦截器不能用,只能使用过滤器。
  • 如果是处理controller前后,既可以使用拦截器也可以使用过滤器。
  • 如果是处理dispaterServlet前后,只能使用过滤器。

过滤器:它依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等

拦截器:它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是直接访问静态资源的请求则没办法进行拦截处理。

两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。

Spring boot使用过滤器

  1. 使用spring boot提供的FilterRegistrationBean注册Filter
  2. 使用原生servlet注解定义Filter 两种方式的本质都是一样的,都是去FilterRegistrationBean注册自定义Filter

方式一

  1. 先定义Filter
    import javax.servlet.*;
    import java.io.IOException;

    public class MyFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {

        }
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            // do something 处理request 或response
            System.out.println("filter1");
            // 调用filter链中的下一个filter
            filterChain.doFilter(servletRequest,servletResponse);
            //如果过滤通过,执行filterChain.doFilter(servletRequest,servletResponse); 不通过就执行直接返回
        }
        @Override
        public void destroy() {

        }
    }
  1. 注册自定义Filter
@Configuration
 public class FilterConfig {   
  @Bean
     public FilterRegistrationBean registrationBean() {
         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
         filterRegistrationBean.addUrlPatterns("/*");
         return filterRegistrationBean;
     }
   }

方式二

@Component
// 定义filterName 和过滤的url
@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*")
public class My2Filter 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("filter2");
        filterChain.doFilter(servletRequest,servletResponse);
        //如果过滤通过,执行filterChain.doFilter(servletRequest,servletResponse); 不通过就执行直接返回
    }
    @Override
    public void destroy() {

    }
}

Spring boot 拦截器的使用

  1. 定义拦截器:
public class MyInterceptor implements HandlerInterceptor {     
  @Override
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         System.out.println("preHandle");
         return true;////如果false,停止流程,api被拦截
       }

       @Override
       public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
         System.out.println("postHandle");
       }

       @Override
       public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
         System.out.println("afterCompletion");
       }
   }
  1. 配置拦截器:
@Configuration
 public class InterceptorConfig implements WebMvcConfigurer {       @Override
       public void addInterceptors(InterceptorRegistry registry) {
           registry.addInterceptor(new MyInterceptor());
       }
   }
  1. Controller演示:
@RestController
 public class UController {
       @GetMapping("/home")
       public String home(){
           System.out.println("home");
           return "myhome";
       }
   }

   输出: 
   preHandle 
   home 
   postHandle 
   afterCompletion

Share this: