filter和Interceptor

简介: 经常做web开发的人员对filter和Interceptor肯定都比较熟悉,它们都可以拦截请求及响应,在实际开发中可用来对参数进行过滤,对请求进行安全校验、记录操作日志,但是两者还是有本质区别。

一、前言

经常做web开发的人员对filter和Interceptor肯定都比较熟悉,它们都可以拦截请求及响应,在实际开发中可用来对参数进行过滤,对请求进行安全校验、记录操作日志,但是两者还是有本质区别。

二、过滤器

过滤器( Filter),是 JavaEE 的标准,依赖于 Servlet 容器,配置在web.xml 文件中,可以配置多个,执行的顺序是根据配置顺序从上到下。

过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是设置字符集、控制权限、控制转向、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一配置请求编码以及过滤一些非法参数,垃圾信息,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。

Filter可以认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应。使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

(一)过滤器的作用

  • 在请求到达serverlt之前拦截客户的HttpServletRequest,获取、修改请求数据
  • 在响应返回客户端之前拦截HttpServletResponse,检查、修改响应数据。

(二)使用场景

  • 负责检查用户请求,根据请求过滤用户非法请求,springsecurity就是通过filter实现
  • 日志Filter:详细记录某些特殊的用户请求
  • 负责解码的Filter:包括对非标准编码的请求解码。

(三)创建方式

  • 实现javax.servlet.Filter接口
  • 继承spring中OncePerRequestFilter类

(四)使用方式

1.在xml中配置

<filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>


2.使用FilterRegistrationBean注册

@ConfigurationpublicclassFilterConfig {
@BeanpublicFilterRegistrationBeantestFilter3RegistrationBean() {
FilterRegistrationBeanregistration=newFilterRegistrationBean(newTestFilter3());
registration.addUrlPatterns("/hello");
registration.setOrder(1); // 值越小越优先执行,此处配置有效returnregistration;
    }
@BeanpublicFilterRegistrationBeantestFilter4RegistrationBean() {
FilterRegistrationBeanregistration=newFilterRegistrationBean(newTestFilter4());
registration.addUrlPatterns("/hello");
registration.setOrder(2);
returnregistration;
    }
}


3.使用@WebFilter 注解配置

在filter上增加@WebFilter注解,在启动类上增加@ServletComponentScan注解

此方式无法通过使用@Order注解来指定filter执行顺序,更详细的原因需要翻看源码。

@WebFilter(urlPatterns="/hello")
publicclassTestFilter1implementsFilter {
@Overridepublicvoidinit(javax.servlet.FilterConfigfilterConfig) throwsServletException {
System.out.println("##############Filter1 init##############");
    }
@OverridepublicvoiddoFilter(ServletRequestservletRequest, ServletResponseservletResponse, FilterChainfilterChain) throwsIOException, ServletException {
//在DispatcherServlet之前执行System.out.println("##############doFilter1 before##############");
filterChain.doFilter(servletRequest, servletResponse);
// 在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后System.out.println("##############doFilter1 after##############");
    }
@Overridepublicvoiddestroy() {
System.out.println("##############Filter1 destroy##############");
    }
}


三、拦截器

拦截器是SpringMVC中实现的一种基于Java反射(动态代理)机制的方法增强工具,拦截器的实现是继承HandlerInterceptor 接口,并实现接口的preHandle、postHandle和afterCompletion方法。

1、preHandle:请求方法前置拦截,该方法会在Controller处理之前进行调用,Spring中可以有多个Interceptor,这些拦截器会按照设定的Order顺序调用,当有一个拦截器在preHandle中返回false的时候,请求就会终止。

2、postHandle:preHandle返回结果为true时,在Controller方法执行之后,视图渲染之前被调用

3、afterCompletion:在preHandle返回ture,并且整个请求结束之后,执行该方法。

(一)创建方式

通过实现HandlerInterceptor接口来创建拦截器

@ComponentpublicclassTestInterceptor1implementsHandlerInterceptor {
@OverridepublicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler) throwsException {
System.out.println("##############TestInterceptor1 preHandle##############");
returntrue;
    }
//在Controller之后的DispatcherServlet之后执行@OverridepublicvoidpostHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, ModelAndViewmodelAndView) throwsException {
System.out.println("##############TestInterceptor1 postHandle##############");
    }
// 在页面渲染完成之后返回给客户端执行@OverridepublicvoidafterCompletion(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, Exceptionex) throwsException {
System.out.println("##############TestInterceptor1 afterCompletion##############");
    }
}



(二)使用方式

通过实现WebMvcConfigurer接口来注册拦截器

@ConfigurerpublicclassWebMvcConfigimplementsWebMvcConfigurer {
@AutowiredprivateTestInterceptor1testInterceptor1;
@AutowiredprivateTestInterceptor2testInterceptor2;
@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry) {
registry.addInterceptor(testInterceptor1)
                .excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg")
                .addPathPatterns("/hello");
registry.addInterceptor(testInterceptor2).addPathPatterns("/hello");
    }
}


四、总结:

  • Filter需要在web.xml中配置,依赖于Servlet;
  • Interceptor需要在SpringMVC中配置,依赖于框架;
  • 两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。
  • 拦截器可以获取IOC容器中的各个bean,而过滤器不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

相关文章
|
1月前
|
前端开发 Java 中间件
过滤器(Filter)和拦截器(Interceptor)有什么不同?
文章比较了过滤器(Filter)和拦截器(Interceptor)的不同,包括它们的实现方式、应用场景、执行顺序、依赖框架和访问范围,指出过滤器通常用于全局和非业务相关的操作,而拦截器用于Spring MVC中与业务逻辑相关的处理。
41 8
|
4月前
|
Python
filter
【7月更文挑战第10天】
40 2
|
6月前
|
缓存 Java Spring
servlet/filter/listener/interceptor区别与联系
servlet/filter/listener/interceptor区别与联系
70 0
|
Java 应用服务中间件 Spring
@RefreshScope和过滤器Filter不要这样用
在注册自定义的OncePerRequestFilter所在的类上加了@RefreshScope导致自定义的OncePerRequestFilter不会被注册到上下文。
|
Web App开发 前端开发
|
Java 数据库连接 容器
拦截器Filter的使用
Filter 程序是一个实现了特殊接口的 Java 类,与 Servlet 类似,也是由 Servlet 容器进行调用和执行的。
134 0
|
安全 Java 容器
SpringMVC - Filter、Interceptor、AOP 区别
SpringMVC - Filter、Interceptor、AOP 区别
224 0
SpringMVC - Filter、Interceptor、AOP 区别
|
XML Java 数据安全/隐私保护
filter和interceptor的区别
filter和interceptor的区别
149 0
|
Java 容器
过滤器(Filter)和拦截器(Interceptor)的区别
来自:http://www.cnblogs.com/luoyun/archive/2013/01/04/2844274.html 过滤器(Filter)和拦截器(Interceptor)的区别 Filter介绍       Filter可以认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。
12100 0
|
容器
Servlet-filter过滤器
Filter的创建过程 实现javax.servlet.Filter接口 实现init方法,读取过滤器的初始化参数 实现doFilter方法,完成对请求或响应的过滤 调用FilterChain接口对象的doFilter方法,向后续的过滤器传递请求或响应 实现过滤器 在Servlet中,如果要定义一个过滤器,则直接让一个类实现javax.
1029 0