Filter和Interceptor

转载:https://www.zifangsky.cn/710.html

1. Filter(过滤器)和 Interceptor(拦截器)的区别

  • 规范不同:FilterServlet规范规定的,依赖于Servlet容器;InterceptorSpring规定的,依赖于Spring框架。
  • 实现原理不同:Filter基于函数回调;Interceptor基于java反射。
  • 使用范围不同:Filter依赖于Servlet容器,只能用于Web程序;Interceptor既可用于Web程序,也可以用于ApplicationSwing等程序中。
  • 使用的资源不同:InterceptorSpring的一个组件,归Spring管理,配置在Spring文件中,可以使用Spring里的任何资源和对象,例如Service对象、数据源、事务管理等,通过IoC注入到Interceptor既可;Filter则不能。
  • 深度不同:Filter只在Servlet前后起作用,Interceptor能够深入到方法前后,异常抛出前后等。在Spring中应该优先使用Interceptor

2. 多个过滤器与多个拦截器的代码执行顺序

如果一个项目中同时有多个Filter,并且有多个Interceptor,那么它们的调用顺序是什么样的呢?

Filter1.java

package com.tao.springstarter.web.filter;

import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Filter1 extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 在DispatcherServlet之前执行
        System.out.println("进入 Filter1 doFilterInternal()");
        // 调用下一个filter
        filterChain.doFilter(request, response);
        // 在试图页面返回给客户端之前执行
        System.out.println("退出 Filter1 doFilterInternal()");
    }
}

Filter2.java

package com.tao.springstarter.web.filter;

import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Filter2 extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 在DispatcherServlet之前执行
        System.out.println("进入 Filter2 doFilterInternal()");
        // 调用下一个filter
        filterChain.doFilter(request, response);
        // 在试图页面返回给客户端之前执行
        System.out.println("退出 Filter2 doFilterInternal()");
    }
}

web.xml中配置Filter1Filter2

	<!-- 注册Filter -->
    <filter>
        <filter-name>Filter1</filter-name>
        <filter-class>com.tao.springstarter.web.filter.Filter1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>Filter2</filter-name>
        <filter-class>com.tao.springstarter.web.filter.Filter2</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Interceptor1.java

package com.tao.springstarter.web.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class Interceptor1 implements HandlerInterceptor {

    /**
     * 在DispatcherServlet之前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行 Interceptor1 preHandle()");
        return true;
    }

    /**
     * 在Controller执行之后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("执行 Interceptor1 postHandle()");
    }

    /**
     * 在页面渲染完成返回给客户端之前执行
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行 Interceptor1 afterCompletion()");
    }
}

Interceptor2.java

package com.tao.springstarter.web.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class Interceptor2 implements HandlerInterceptor {
    /**
     * 在DispatcherServlet之前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行 Interceptor2 preHandle()");
        return true;
    }

    /**
     * 在Controller执行之后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("执行 Interceptor2 postHandle()");
    }

    /**
     * 在页面渲染完成返回给客户端之前执行
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行 Interceptor2 afterCompletion()");
    }
}

spring-servlet.xml中配置Interceptor1Interceptor2

	<mvc:interceptors>
        <!-- 公共拦截器Interceptor1, 对所有请求都拦截 -->
        <bean name="interceptor1" class="com.tao.springstarter.web.interceptor.Interceptor1"/>
        <!-- 特定拦截器Interceptor2 -->
        <mvc:interceptor>
            <!-- 对/test进行拦截 -->
            <mvc:mapping path="/test"/>
            <!-- 特定请求的拦截器只能有一个 -->
            <bean name="interceptor2" class="com.tao.springstarter.web.interceptor.Interceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

测试用的TestController:

package com.tao.springstarter.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {

    @RequestMapping("/test")
    @ResponseBody
    public String filterAndInterceptor1() {
        System.out.println("调用 TestController#filterAndInterceptor1()");
        return "filterAndInterceptor1";
    }

    @RequestMapping("/haha")
    @ResponseBody
    public String filterAndInterceptor2() {
        System.out.println("调用 TestController#filterAndInterceptor2()");
        return "filterAndInterceptor2";
    }
}

请求http://localhost:8080/ss/test
在这里插入图片描述

请求http://localhost:8080/ss/haha
在这里插入图片描述
可以看到此时Interceptor2没有起作用。

其最终的执行流程就如下图所示:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值