一.过滤器和拦截器的区别
1、滤波器和拦截器的触发时机不同。 过滤器在请求访问容器之后,但在请求访问servlet之前进行预处理。 请求结束后返回也是在servlet处理结束后返回前端之前。
2、拦截器可以获取IOC容器中的每个bean,但不能过滤。 拦截器由spring提供和管理,因此拦截器可以使用spring功能。 可以向拦截器注入服务以调用业务逻辑。 过滤器是JavaEE标准,只依赖servlet API,不需要依赖spring。
3、滤波器的实现基于回调函数。 拦截器(代理模式)的实现基于反射
4、过滤器依赖于servlet容器,是servlet规范的一部分,但拦截器是独立存在的,可以在任何情况下使用。
5、过滤器的执行通过servlet容器的回调进行,拦截器通常以动态代理(反射)方式执行。
6、过滤器的生命周期由servlet容器管理,拦截器由IoC容器管理,通过注入等方式可以获取其他Bean的实例,使用方便。
过滤器和拦截器很相似,但有很大的区别
最明显的区别是,**过滤器可以修改请求,但不能拦截器
过滤器必须在servlet容器中实现,拦截器可以应用于javaEE、javaSE等各种环境
拦截器可以调用IOC容器中的各种依赖关系,但过滤器不能
过滤器只能在请求前后使用,但拦截器采用各种方法**
差异很多,请大家调查一下
总的来说
过滤器是筛选你想要的东西。 例如,requeset中你想要的部分
拦截器在安全方面被广泛使用,例如结束一些过程
网上有很好的照片。 请复印在这里给我看
过滤器(Filter ) :可以获取原始http请求,但无法获取请求的控制器和请求控制器中方法的信息。
拦截器可以获得你请求的控制器和方法,但不能获得请求方法的参数。
切片:可以获得方法的参数,但不能获得http请求和响应对象。
二、过滤器两种方式:
1、使用spring boot提供的过滤器注册过滤器
2、用本机servlet注释定义Filter
这两种方式的本质都相同,都是在FilterRegistrationBean中注册自定义过滤器
方式一: (使用spring boot提供的FilterRegistrationBean注册filter (http://www.Sina.com /
package com.corwien.filter; 导入javax.servlet.*; import java.io.IOException; publicclassmyfilterimplementsfilter { @ overridepublicvoidinit (filterconfigfilterconfig ) throws ServletException { } @ overridepublicvoiddofilter (servletrequestservletrequest,ServletResponse servletResponse, 过滤器通道过滤器通道) throws servlet exception {//do something处理request或response //doFilter ()方法的servletRequest参数必须转换为HttpServletRequest过滤器链中的下一个filterhttpservletrequestrequest=(http servletrequest ) servlet request; http servlet响应=(http servlet响应) servlet响应; String ip=request.getRemoteAddr (; string URL=request.getrequest URL ().toString ); simpledateformatsdf=newsimpledateformat (yyyy-mm-ddhh : mm : ss ); 日期d=new date (; stringdate=SDF.format(d; system.out.printf('%s%s已访问%s%n”、date、ip和url ); filter chain.do filter (请求,响应; } @Ov
erride 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)压缩响应信息