Springboot过滤器和拦截器详解及使用场景

一、过滤器和拦截器的区别
Springboot过滤器和拦截器详解及使用场景文章插图
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中你要的那部分拦截器在做安全方面用的比较多 , 比如终止一些流程网上有一张图片很不错 , 这里拷过来给大家看一下
Springboot过滤器和拦截器详解及使用场景文章插图
过滤器(Filter) :可以拿到原始的http请求 , 但是拿不到你请求的控制器和请求控制器中的方法的信息 。
拦截器(Interceptor):可以拿到你请求的控制器和方法 , 却拿不到请求方法的参数 。
切片(Aspect): 可以拿到方法的参数 , 但是却拿不到http请求和响应的对象
Springboot过滤器和拦截器详解及使用场景文章插图
二、过滤器两种方式: 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链中的下一个filterHttpServletRequest 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 {@Beanpublic 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() {}