文章内容
在日常的开发中,经常会用到Filter和Interceptor。有时同一个功能。Filter可以做,Interceptor也可以做。有时就需要考虑使用哪一个比较好。
一、Filter和Interceptor的区别
1、Filter
过滤器(Filter)是在请求进入Tomcat容器之后,请求进入Servlet之前执行。Filter是Servlet规范规定的,只能用于web程序中。
2、Interceptor
拦截器(Interceptor)是在Servlet和Controller控制器之间执行。Interceptor是SpringframeWork中规定的。

- Interceptor是基于java的反射机制的,而Filter是基于函数回调。
- Interceptor不依赖与servlet容器,Filter依赖与servlet容器。
- Interceptor只能对action请求起作用,而Filter则可以对几乎所有的请求起作用。
- Interceptor可以访问action上下文、值栈里的对象,而Filter不能访问。
- Interceptor以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。拦截器可以获取ioc中的service bean实现业务逻辑。
二、Spring MVC中的实现
Spring MVC中每个控制器中可以定义多个请求处理方法,我们把这种请求处理方法简称为Action。
1、Filter的实现
自己的filter需要要实现javax.servlet.Filter。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | import javax.servlet.*; import java.io.IOException; public class Myfilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println( "Myfilter init" ); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println( "Myfilter doFilter before" ); filterChain.doFilter(servletRequest,servletResponse); System.out.println( "Myfilter doFilter after" ); } @Override public void destroy() { System.out.println( "Myfilter destroy" ); } } |
注册Filter在web.xml中:
1 2 3 4 5 6 7 8 9 | <!-- 注册过滤器 --> < filter > < filter-name >myfilter</ filter-name > < filter-class >com.hardy.config.Myfilter</ filter-class > </ filter > < filter-mapping > < filter-name >myfilter</ filter-name > < url-pattern >/*</ url-pattern > </ filter-mapping > |
2、Interceptor的实现
自己的Interceptor需要要实现org.springframework.web.servlet.HandlerInterceptor。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在拦截点(Controller方法处理之前)执行拦截 若返回的是false则中断执行 反之亦然 System.out.println( "MyInterceptor preHandle" ); return HandlerInterceptor. super .preHandle(request, response, handler); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在处理过程中(Controller方法处理完之后 DispatcherServlet进行视图的渲染之前)执行拦截 System.out.println( "MyInterceptor postHandle" ); HandlerInterceptor. super .postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在DispatcherServlet进行视图的渲染后 返回前进行拦截 System.out.println( "MyInterceptor afterCompletion" ); HandlerInterceptor. super .afterCompletion(request, response, handler, ex); } } |
注册Interceptor在spring的配置文件中(application.xml):
01 02 03 04 05 06 07 08 09 10 11 12 | <!-- 配置拦截器 --> < mvc:interceptors > < mvc:interceptor > <!-- 拦截所有的mvc控制器(Controller) --> < mvc:mapping path = "/**" /> <!-- 放行机制 指定对某个页面不进行拦截 --> <!-- 拦截器只对action起作用 因此填入的不是页面路径 而是方法 --> < mvc:exclude-mapping path = "/login" /> <!-- 指定使用哪个拦截器 --> < bean class = "com.hardy.config.MyInterceptor" /> </ mvc:interceptor > </ mvc:interceptors > |