目录

一、过滤器(Filter)

1. 概念

2. 作用

3. 创建Filter处理类

二、拦截器 

1. 概念

2. 作用        

3. 创建Interceptor处理类

 三、过滤器和拦截器的区别

1. 相同点 

2. 不同点


一、过滤器(Filter)

1. 概念

        过滤器(Filter)是基于Servlet实现的,主要的应用场景是设置字符集、控制权限、控制转向、跨域等。Servlet的工作原理是当你在web.xml文件中配置好需要拦截的客户端请求,它就会拦截到你所需要拦截的请求,然后对请求或响应(Request、Response)进行处理。同时还可以进行逻辑判断,如用户是否已经登录、有没有权限访问该页面等工作。Filter过滤器随着web应用的启动而启动,只初始化一次。启动后就可以拦截相关请求,只有当该web应用程序停止或重新部署的时候才销毁。

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

2. 作用

  • 在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
  • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
  • 在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
  • 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

3. 创建Filter处理类

        需要实现javax.servlet.Filter接口,并重写该接口中的方法。

  • void init(FilterConfig config) : 用于完成Filter的初始化,只会初始化一次。
  • void destory() : 当容器销毁时,执行destory方法,只会被调用一次。
  • void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) : 实现过滤功能,该方法就是对每个请求及响应增加的额外处理。该方法可以实现对用户请求进行预处理(ServletRequest request),也可实现对服务器响应进行后处理(ServletResponse response)—它们的分界线为是否调用了chain.doFilter(),执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。
import javax.servlet.*;
import java.io.IOException;

public class FilterTest implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化拦截器");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //做一些处理
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("拦截器已销毁");
    }
}

二、拦截器 

1. 概念

        拦截器是SpringMVC中实现的一种基于Java反射(动态代理)机制的方法增强工具,SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式:

  1. 第一种方式是要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ,并重写preHandle、postHandle和afterCompletion方法。;
  2. 第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类,并重写preHandle、postHandle和afterCompletion方法。

2. 作用        

  • 乱码问题:用request,response参数去设置编码;
  • 解决权限验证问题(是否登陆,取session对象查看);
  • 可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。

3. 创建Interceptor处理类

        需要实现org.springframework.web.servlet.HandlerInterceptor接口,并重写该接口中的方法。

  • preHandle:请求方法前置拦截,该方法会在Controller处理之前进行调用,Spring中可以有多个Interceptor,这些拦截器会按照设定的Order顺序调用,当有一个拦截器在preHandle中返回false的时候,请求就会终止。
  • postHandle:preHandle返回结果为true时,在Controller方法执行之后,视图渲染之前被调用
  • afterCompletion:在preHandle返回ture,并且整个请求结束之后,执行该方法。
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

 三、过滤器和拦截器的区别

        在知道过滤器和拦截器分别是什么之后。我们就来区分一下两者之间的异同吧。

1. 相同点 

  • 拦截器与过滤器都是体现了AOP的思想,对方法实现增强,都可以拦截请求方法。
  • 拦截器和过滤器都可以通过Order注解设定执行顺序

2. 不同点

  • 拦截器Interceptor依赖于框架容器,基于反射机制,只过滤请求;
  • 过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围大;
  • 过滤器可对所有请求起作用,拦截器只对action请求起作用;
  • 在action的声明周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次;

这两个之间最大的区别就是,过滤器可以包装Request和Response,而拦截器并不能。