Springboot过滤器和详解及使⽤场景
⼀、过滤器和的区别
进⼊servlet之前进⾏预处理
⾏预处理的。请求结束返回也是,是在servlet
求进⼊容器后,但请求进⼊servlet之前
过滤器是在请求进⼊容器后
1、过滤器和触发时机不⼀样
触发时机不⼀样,过滤器是
处理完后,返回给前端之前。
截器是spring提供并管理的,spring的功能可以被使⽤,在拦截2、
可以获取IOC容器中的各个bean,⽽过滤器就不⾏,因为是spring提供并管理的
器⾥注⼊⼀个service,可以调⽤业务逻辑。⽽过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。
(代理模式)的实现基于反射
基于反射
回调函数。⽽
过滤器的实现基于回调函数
3、过滤器的实现
属于Servlet规范的⼀部分,⽽则是独⽴存
则是独⽴存在的,可以在任何情况下使⽤。
Filter是依赖于Servlet容
赖于Servlet容器,属于Servlet规范的⼀部分
4、Filter
通常通过动态代理(反射)
过动态代理(反射)的⽅式来执⾏。
Servlet容器回调完成,⽽
Filter的执⾏由Servlet容器回调完成
5、Filte
spring ioc注解则可以通过IoC容器来管理
oC容器来管理,因此可以通过注⼊等⽅式来获取其他Bean的实例,因此使由Servlet容器管理,⽽则
Filter的⽣命周期由Servlet容器管理
6、Filter的⽣命周
⽤会更⽅便。
过滤器和⾮常相似,但是它们有很⼤的区别
最简单明了的区别就是**过滤器可以修改request,⽽不能
过滤器需要在servlet容器中实现,可以适⽤于javaEE,javaSE等各种环境
可以调⽤IOC容器中的各种依赖,⽽过滤器不能
过滤器只能在请求的前后使⽤,⽽可以详细到每个⽅法**
区别很多,⼤家可以去查下
总的来说
过滤器就是筛选出你要的东西,⽐如requeset中你要的那部分
在做安全⽅⾯⽤的⽐较多,⽐如终⽌⼀些流程
⽹上有⼀张图⽚很不错,这⾥拷过来给⼤家看⼀下
过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的⽅法的信息。(Interceptor):可以拿到你请求的控制器和⽅法,却拿不到请求⽅法的参数。
切⽚(Aspect): 可以拿到⽅法的参数,但是却拿不到http请求和响应的对象
⼆、过滤器
两种⽅式:
FilterRegistrationBean注册Filter
1、使⽤spring boot提供的FilterRegistrationBean注册Filter
1、
原⽣servlet注解定义Filter
2、使⽤原⽣servlet注解定义Filter
2、
都是去FilterRegistrationBean注册⾃定义Filter
两种⽅式的本质都是⼀样的,都是去FilterRegistrationBean注册⾃定义Filter
⽅式⼀: (使⽤spring boot提供的FilterRegistrationBean注册Filter )
①、先定义Filter:
pServletRequest request = (HttpServletRequest) servletRequest;      HttpServletResponse response = (HttpServletResponse) servletResponse;        String ip = RemoteAddr();      String url = RequestURL().toString();        SimpleDateFormat sdf =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");      Date d =newDate();        String date = sdf.format(d);        System.out.printf("%s %s 访问了 %s%n", date, ip, url);              filterChain.doFilter(request, response);    }@Overridepublicvoiddestroy(){    }}
②、注册⾃定义Filter
@ConfigurationpublicclassFilterConfig{@BeanpublicFilterRegistrationBeanregistrationBean(){      ** FilterRegistrationBean filterRegistrationBean =newFilterRegistrationBean(new** **MyFilter());**
filterRegistrationBean.addUrlPatterns("/*");returnfilterRegistrationBean;    }}
⽅式⼀的①②步骤可以⽤下⾯这段代码代替:
@ConfigurationpublicclassFilterConfig{@Beanpublic**FilterRegistrationBean** registFilter() {        **FilterRegistrationBean registration** **=newFilterRegistrationBean();        registration.setFilter(new** **LogCostFilter());**
registration.addUrlPatterns("/*");        registration.setName("LogCostFilter");        registration.setOrder(1);returnregistration;    } }
publicclassLogCostFilterimplementsFilter{@Overridepublicvoidinit(FilterConfig filterConfig)throwsServletException{
}@OverridepublicvoiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain
filterChain)throwsIOException, ServletException{longstart = System.currentTimeMillis();
filterChain.doFilter(servletRequest,servletResponse);        System.out.println("Execute cost="+(System.currentTimeMillis()-start));    }@Overridepublicvoiddestroy(){    }
⽅式⼆:(使⽤
⽅式⼆:(使⽤原⽣servlet注解定义Filter )
/
/ 注⼊spring容器@Component// 定义filterName 和过滤的url@WebFilter(filterName ="my2Filter",urlPatterns ="/*") public class
My2Filter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {    }@Overridepublic
void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("filter2");    }    @Overridepublicvoiddestroy() {    }}
以设置url匹配模式,过滤器名称等。这⾥需要注意⼀点的是@WebFilter这个注解是
@WebFilter这个注解是@WebFilter就可以进⾏配置,同样,可以设置url匹配模式,过滤器名称
这⾥直接⽤@WebFilter就
启动类中加另外⼀个注解:
Servlet3.0的规范,并不是Spring boot提供的。除了这个注解以外,我们还需在启动类中加另外⼀个注解:
Servlet3.0的规范,并不是Spring boot提供
@ServletComponetScan,指定扫描的包。
三、的配置
实现可以通过继承 HandlerInterceptorAdapter类也可以通过实现HandlerInterceptor这个接⼝。另外,如果preHandle⽅法return true,则继续后续处理。
⾸先我们实现类:
publicclassLogCostInterceptorimplementsHandlerInterceptor{longstart =
System.currentTimeMillis();@OverridepublicbooleanpreHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)throwsException{        start = System.currentTimeMillis();returntrue;
}@OverridepublicvoidpostHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView)throwsException{        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));    }@Overridepublicvoidaft
erCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e)throwsException{    }}
reHandle是请求执⾏前执⾏的,postHandler是请求结束HandlerInterceptor这个接⼝,这个接⼝包括三个⽅法,preHandle是请求执⾏前
postHandler是请求结束执还需要实现HandlerInterceptor这个接⼝
我们还需要
afterCompletion是视图渲染完成后才执⾏,同样需要preHandle返回true,⾏的,但只有preHandle⽅法返回true的时候才会执
只有preHandle⽅法返回true的时候才会执⾏,afterCompletion是视图渲染完成后才执⾏
该⽅法通常⽤于清理资源等⼯作。除了实现上⾯的接⼝外,我们还需对其进⾏配置:
@ConfigurationpublicclassInterceptorConfigextendsWebMvcConfigurerAdapter{@OverridepublicvoidaddInterceptors(Intercept orRegistry registry){
registry.addInterceptor(newLogCostInterceptor()).addPathPatterns("/**");super.addInterceptors(registry);    }}
重写了addInterceptors这个⽅法,进⾏的配置,主要配置项就两
主要配置项就两继承了WebMVCConfigurerAdapter,这⾥我们重写了addInterceptors这个⽅法
这⾥我们继承了WebMVCConfigurerAdapter
指定拦截的URL。
个,⼀个是指定
指定,第⼆个是指定拦截的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)压缩响应信息

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。