一、过滤器和拦截器的区别

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

2、拦截器能够获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并治理的,spring的性能能够被拦截器应用,在拦截器里注入一个service,能够调用业务逻辑。而过滤器是JavaEE规范,只需依赖servlet api ,不须要依赖spring。

3、过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射

4、Filter是依赖于Servlet容器,属于Servlet标准的一部分,而拦截器则是独立存在的,能够在任何状况下应用。

5、Filter的执行由Servlet容器回调实现,而拦截器通常通过动静代理(反射)的形式来执行。

6、Filter的生命周由Servlet容器治理,而拦截器则能够通过IoC容器来治理,因而能够通过注入等形式来获取其余Bean的实例,因而应用会更不便。

过滤器和拦截器十分类似,然而它们有很大的区别
最简单明了的区别就是**过滤器能够批改request,而拦截器不能
过滤器须要在servlet容器中实现,拦截器能够实用于javaEE,javaSE等各种环境
拦截器能够调用IOC容器中的各种依赖,而过滤器不能
过滤器只能在申请的前后应用,而拦截器能够具体到每个办法**
区别很多,大家能够去查下

总的来说
过滤器就是筛选出你要的货色,比方requeset中你要的那局部
拦截器在做平安方面用的比拟多,比方终止一些流程
网上有一张图片很不错,这里拷过去给大家看一下

过滤器(Filter) :能够拿到原始的http申请,然而拿不到你申请的控制器和申请控制器中的办法的信息。

拦截器(Interceptor):能够拿到你申请的控制器和办法,却拿不到申请办法的参数。

切片(Aspect): 能够拿到办法的参数,然而却拿不到http申请和响应的对象

二、过滤器

两种形式: 
1、应用spring boot提供的FilterRegistrationBean注册Filter
2、应用原生servlet注解定义Filter 
两种形式的实质都是一样的,都是去FilterRegistrationBean注册自定义Filter

形式一: (应用spring boot提供的FilterRegistrationBean注册Filter )
①、先定义Filter:

package com.corwien.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     // doFilter()办法中的servletRequest参数的类型是ServletRequest,须要转换为HttpServletRequest类型不便调用某些办法      System.out.println("filter1"); // 调用filter链中的下一个filter   HttpServletRequest request = (HttpServletRequest) servletRequest;        HttpServletResponse response = (HttpServletResponse) servletResponse;         String ip = request.getRemoteAddr();        String url = request.getRequestURL().toString();        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        Date d = new Date();        String date = sdf.format(d);         System.out.printf("%s %s 拜访了 %s%n", date, ip, url);                filterChain.doFilter(request, response);    }    @Override public void destroy() {    }}

②、注册自定义Filter

@Configurationpublic class FilterConfig {    @Bean    public FilterRegistrationBean registrationBean() {       ** FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new** **MyFilter());**        filterRegistrationBean.addUrlPatterns("/*");        return filterRegistrationBean;    }}

形式一的①②步骤能够用上面这段代码代替:

@Configuration public class FilterConfig {     @Bean public **FilterRegistrationBean** registFilter() {        **FilterRegistrationBean registration** **= new FilterRegistrationBean();        registration.setFilter(new** **LogCostFilter());**        registration.addUrlPatterns("/*");        registration.setName("LogCostFilter");        registration.setOrder(1); return registration;    } }
public class LogCostFilter implements Filter {    @Override public void init(FilterConfig filterConfig) throws ServletException {     }     @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { long start = System.currentTimeMillis();        filterChain.doFilter(servletRequest,servletResponse);        System.out.println("Execute cost="+(System.currentTimeMillis()-start));    }     @Override public void destroy() {     }

形式二:(应用原生servlet注解定义Filter )

// 注入spring容器@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");    }    @Override public void destroy() {    }}

这里间接用@WebFilter就能够进行配置,同样,可以设置url匹配模式,过滤器名称等。这里须要留神一点的是@WebFilter这个注解是Servlet3.0的标准,并不是Spring boot提供的。除了这个注解以外,咱们还需在启动类中加另外一个注解:@ServletComponetScan,指定扫描的包。

三、拦截器的配置

实现拦截器能够通过继承 HandlerInterceptorAdapter类也能够通过实现HandlerInterceptor这个接口。另外,如果preHandle办法return true,则持续后续解决。

首先咱们实现拦截器类:

public class LogCostInterceptor implements HandlerInterceptor { long start = System.currentTimeMillis();    @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {        start = System.currentTimeMillis(); return true;    }     @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));    }     @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {    }}

咱们还须要实现HandlerInterceptor这个接口,这个接口包含三个办法,preHandle是申请执行前执行的,postHandler是申请完结执行的,但只有preHandle办法返回true的时候才会执行,afterCompletion是视图渲染实现后才执行,同样须要preHandle返回true,该办法通常用于清理资源等工作。除了实现下面的接口外,咱们还需对其进行配置:

@Configuration public class InterceptorConfig extends WebMvcConfigurerAdapter {     @Override public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**"); super.addInterceptors(registry);    }}

这里咱们继承了WebMVCConfigurerAdapter,这里咱们重写了addInterceptors这个办法,进行拦截器的配置,次要配置项就两个,一个是指定拦截器,第二个是指定拦挡的URL

坑坑坑:
拦截器不失效常见问题:
1)是否有加@Configuration
2)拦挡门路是否有问题 ***
3)拦截器最初门路肯定要 “/**”, 如果是目录的话则是 /*/

总结一下:创立拦截器须要两步:

1、自定义拦截器
2、注册拦截器

四、利用场景

拦截器是在DispatcherServlet这个servlet中执行的,因而所有的申请最先进入Filter,最初来到Filter。其程序如下。

Filter->Interceptor.preHandle->Handler->Interceptor.postHandle->Interceptor.afterCompletion->Filter

拦截器利用场景

拦截器实质上是面向切面编程(AOP),合乎横切关注点的性能都能够放在拦截器中来实现,次要的利用场景包含:

  • 登录验证,判断用户是否登录。
  • 权限验证,判断用户是否有权限拜访资源,如校验token
  • 日志记录,记录申请操作日志(用户ip,拜访工夫等),以便统计申请访问量。
  • 解决cookie、本地化、国际化、主题等。
  • 性能监控,监控申请解决时长等。
  • 通用行为:读取cookie失去用户信息并将用户对象放入申请,从而不便后续流程应用,还有如提取Locale、Theme信息等,只有是多个处理器都须要的即可应用拦截器实现)

过滤器利用场景

1)过滤敏感词汇(避免sql注入)
2)设置字符编码
3)URL级别的权限访问控制
4)压缩响应信息


相干文章:
spring boot 过滤器、拦截器的区别与应用
springboot下应用拦截器和过滤器
SpringBoot2.x拦截器与过滤器的利用场景及配置