过滤器(Filter)、拦截器(Interceptor)的区别及使用

在区别过滤器和拦截器之前我们先来了解一下SpringMVC的执行流程

springMVC执行流程图spring工作流程描述:

  1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
  2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
  3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
  4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)
  5. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
  6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
  7. ViewResolver 结合Model和View,来渲染视图
  8. 将渲染结果返回给客户端。

知道了SpringMVC执行的流程了下面来说Filter和Interceptor的区别

Filter

Filter是依赖于Servlet容器的,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest以及HttpServletResponse的一些参数,包括:过滤低俗文字、危险字符等。

Filter主要有以下几个用途:

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

关于如何修改参数,这篇博客讲的很好:在Filter中修改HttpServletRequest的参数

Interceptor

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。

Filter和Interceptor的区别

  1. Filter依赖于Servlet容器,而Interceptor依赖于Web框架;
  2. Filter对几乎所有的请求起作用,而Interceptor只能对Controller的action请求起作用;
  3. 在Controller的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。

Filter和Interceptor的执行顺序

只有一个Filter和Interceptor时
过滤前->拦截前->Controller的action执行->拦截后->过滤后

有多个Filter和Interceptor时
Filter和Interceptor之间的执行顺序不变,而多个Filter和多个Interceptor的执行顺序和它们的配置顺序是一致的。

//在web.xml文件中配置Filter
	<!-- 自定义过滤器:testFilter1 -->
<filter>
		<filter-name>testFilter1</filter-name>
		<filter-class>com.ding.TestFilter1</filter-class>
</filter>
<filter-mapping>
		<filter-name>testFilter1</filter-name>
		<url-pattern>/*</url-pattern>
</filter-mapping>
	<!-- 自定义过滤器:testFilter2 -->	
 <filter>
		<filter-name>testFilter2</filter-name>
		<filter-class>com.ding.TestFilter2</filter-class>
</filter>
<filter-mapping>
		<filter-name>testFilter2</filter-name>
		<url-pattern>/*</url-pattern>
</filter-mapping>


//在spring-mvc.xml配置文件中配置Interceptor
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.ding.interceptor.TestInterceptor1" />
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.ding.interceptor.TestInterceptor2" />
        </mvc:interceptor>
</mvc:interceptors>

根据它们的配置顺序,执行顺序为:
testFilter1->testFilter2->TestInterceptor1->TestInterceptor2->Controller中的action执行->TestInterceptor2->TestInterceptor1->testFilter2->testFilter1

Interceptor的应用——实现登录验证

当使用到springmvc做登录模块的时候,总会遇到需要判断用户是否合法登录,一般的做法就是用拦截器判断用户的session是否为空,通过拦截器获取到用户session里面的数据,判断是否未登录或者未合法登录,如果未登录就重定向到登录页面。

拦截器拦截登录的例子:

import com.ding.model.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * 自定义的拦截器,实现HandlerInterceptor 
 */
public class UserInterceptor implements HandlerInterceptor {
   
    /**
     *成功获得HandlerAdapter后,在Handler执行之前调用这个方法
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String path = httpServletRequest.getServletPath();
        if ("/user/userLogin".equals(path)){//登陆接口
            return true;
        } else {//其他接口
            //获取用户的session
            User user = (User) httpServletRequest.getSession().getAttribute("user");
            if (user == null){//未登录
                //重定向
                httpServletResponse.sendRedirect("/user/userLogin");
                return false;
            } else {//已登录
                return true;
            }
        }
    }


    /**
     * Handler执行完成之后调用这个方法
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     *Handler执行之后,ModelAndView返回之前调用这个方法
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

参考文章:https://blog.csdn.net/xiaoyaotan_111/article/details/53817918

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值