Spring中过滤器(Filter)和拦截器(Interceptor)的区别和联系

在日常的开发中,经常会用到Filter和Interceptor。有时同一个功能。Filter可以做,Interceptor也可以做。有时就需要考虑使用哪一个比较好。

一、Filter和Interceptor的区别

1、Filter

过滤器(Filter)是在请求进入Tomcat容器之后,请求进入Servlet之前执行。Filter是Servlet规范规定的,只能用于web程序中。

2、Interceptor

拦截器(Interceptor)是在Servlet和Controller控制器之间执行。Interceptor是SpringframeWork中规定的。

Spring中过滤器(Filter)和拦截器(Interceptor)的区别和联系插图
  • 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>

发表评论

欢迎阅读『Spring中过滤器(Filter)和拦截器(Interceptor)的区别和联系|Java、Spring Boot、开源组件|Nick Tan-梓潼Blog』