解读过滤器(Filter)和拦截器(Interceptor)的使用

 更新时间:2025年06月29日 14:15:21   作者:找不到、了  
这篇文章主要介绍了过滤器(Filter)和拦截器(Interceptor)的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

关于SpringMVC的完整执行流程,可如下图所示:

整体的流程如下所示:

Request请求-->filterInit--->dofilter--->dispatcherServlet---->InterceptorPrehandler--->Controller-------InterceptorPosthandler------>dispatcherServlet---InterceptorAftercomption-->filterDestroy

关于过滤器和拦截器在web容器里面的先后顺序,可参考如下所示:

下面重点介绍下两者的区别和联系。

1、定义介绍

1.1、过滤器Filter

1、定义

是 Servlet 规范规定的,在 Servlet 前执行的,用于拦截和处理 HTTP 请求和响应。拦截的是request请求,基于回调,拦截的是地址,粒度很大。

2、方法

通过实现Filter接口,分别是初始化方法dofilter方法和销毁方法随着容器的启动和销毁而初始化和销毁,依赖于servlet容器。

过滤器拦截的是地址栏请求,过滤器实在进入容器后执行的servlet之前后执行,针对的在处理业务之前的操作。

chain.doFilter(request, response);这个方法的调用作为分水岭。事实上调用Servlet的doService()方法是在这个方法中进行的。

3、位置

位于整个请求处理流程的最前端,因此在请求到达 Controller 层前,都会先被过滤器处理。可以拦截多个请求或响应一个请求或响应也可以被多个过滤器拦截

4、使用场景

可用于身份认证、授权、日志记录和设置字符集(CharacterEncodingFilter)等场景。

1.2、拦截器Interceptor

1、介绍

基于Java的jdk动态代实现的,实现HandlerInterceptor接口,不依赖于servlet容器。

拦截器针对于controller方法,并且能获取到所有的类,对类里面所有的方法实现拦截,粒度更小,拦截器中可以注入service,也可以调用业务逻辑

2、方法

实现HandlerInterceptor接口。重写preHandle()、postHandle()、afterCompletion();

3、执行顺序

执行结果如下:

/*
0:过滤器1的初始化方法
1:过滤器1,客户端向Servlet发送的请求被我拦截到了
2:拦截器1的前置方法 preHandle
3:拦截器2的前置方法 preHandle
4: controller主方法
5:拦截器2的后置方法postHandle(在controller主方法执行之后执行)
6:拦截器1的后置方法postHandle(在controller主方法执行之后执行)
7:拦截器2的完成后方法afterCompletion(在DispatcherServlet处理完请求后,才会执行)
8:拦截器1的完成后方法afterCompletion(在DispatcherServlet处理完请求后,才会执行)
9:过滤器1,Servlet向客户端发送的响应被我拦截到了
10:过滤器的销毁方法
*/

2、实现方式

2.1、过滤器实现方式

1、通过@WebFilter注解(Servlet 3.0+)

@WebFilter(urlPatterns = "/*", filterName = "myFilter")
public class MyFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化代码
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                         FilterChain chain) throws IOException, ServletException {
        // 前置处理
        System.out.println("Before Filter");
        
        // 执行后续过滤器或Servlet
        chain.doFilter(request, response);
        
        // 后置处理
        System.out.println("After Filter");
    }

    @Override
    public void destroy() {
        // 销毁代码
    }
}

2、xml配置:

<filter>
      <filter-name>filterDemo1</filter-name>
      <filter-class>com.thit.filters.Filter1</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>filterDemo1</filter-name>
      <url-pattern>/*</url-pattern>
      <!-- /*是对所有的文件进行拦截 -->
  </filter-mapping>

多个Filter的执行顺序:

  • 注解方式:按类名字母顺序执行
  • web.xml方式:<filter-mapping>定义的顺序执行

2.2、拦截器实现方式

1:实现WebMvcConfigurer接口(Spring 5+推荐)

//拦截器1
public class LoginInterceptor implements HandlerInterceptor{
	
 
	//预处理1.程序先执行preHandle()方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行。
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("1:拦截器1,程序进入preHandle方法");
		User u=(User) request.getSession().getAttribute("user");
		if(u==null) {
			System.out.println("在进入方法之前判断session的用户是否为空!");
			System.out.println("地址:"+request.getContextPath());
			//http://localhost:8080/login
			response.sendRedirect(request.getContextPath()+"/login");
			return false;
		}
 
		return true;
	}
	//后处理 	2.在业务处理器(即控制器Controller类)处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回响应。
 
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("2:拦截器1,程序进入postHandle方法");
		
	}
	//完工之后 	3.在DispatcherServlet处理完请求后,才会执行afterCompletion()方法。
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("3:拦截器1,程序进入afterCompletion方法");
		
	}
 
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**")  // 拦截所有路径
                .excludePathPatterns("/login"); // 排除登录路径
        
        // 可以添加多个拦截器
        registry.addInterceptor(new AnotherInterceptor())
                .addPathPatterns("/admin/**");
    }
}

2:XML配置

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/login"/>
        <bean class="com.example.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3、两者联系与区别

3.1、联系

3.2、区别

4、总结

两者都是AOP编程思想的实现,都能够实现权限控制和日志记录等问题的处理,但是两者粒度不同拦截对象不一样。

  • 1、适用范围不同

Filter是servlet的规范,只能用于web程序,但是拦截器可以用于application等程序。

  • 2、规范不同:

Filter是servlet的规范。但是Interceptor是Spring容器支撑,有Spring框架支持。

  • 3、使用资源不一样:

Spring的拦截器由于依赖Spring,也是Spring的一个组件,因此能够在拦截器中使用Spring的任何资源和对象。

例如Service对象,数据源,事务管理等,通过ioc注入拦截器即可,而filter不能.

  • 4、粒度不同:

Filter只能在servlet的前后起作用,而拦截器能在方法前后异常前后执行,更加灵活,粒度更小,Spring框架程序优先使用拦截器。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅析SpringBoot统一返回结果的实现

    浅析SpringBoot统一返回结果的实现

    前后端开发过程中数据交互规范化是一件非常重要的事情,不仅可以减少前后端交互过程中出现的问题,也让代码逻辑更加具有条理,下面小编就和大家讲讲SpringBoot如何统一返回结果的吧
    2023-07-07
  • Java软件设计模式之桥接模式详解

    Java软件设计模式之桥接模式详解

    这篇文章主要介绍了Java软件设计模式之桥接模式详解,桥接模式也叫做桥梁模式,结构型设计模式的一种,顾名思义,就是用来连接两个部分,为被分离了的抽象部分和实现部分搭桥,需要的朋友可以参考下
    2023-07-07
  • Spring Data Jpa框架最佳实践示例

    Spring Data Jpa框架最佳实践示例

    这篇文章主要为大家介绍了Spring Data Jpa框架最佳实践示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-02-02
  • Java中实现List分隔成子List详解

    Java中实现List分隔成子List详解

    大家好,本篇文章主要讲的是Java中实现List分隔成子List详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • 手把手搭建Java共享网盘的方法步骤

    手把手搭建Java共享网盘的方法步骤

    这篇文章主要介绍了手把手搭建Java共享网盘,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • idea创建SpringBoot自动创建Lombok无效果的问题解决方案

    idea创建SpringBoot自动创建Lombok无效果的问题解决方案

    这篇文章主要介绍了idea创建SpringBoot自动创建Lombok无效果的问题解决方案,感兴趣的朋友跟随小编一起看看吧
    2024-12-12
  • StackTraceElement获取方法调用栈信息实例详解

    StackTraceElement获取方法调用栈信息实例详解

    这篇文章主要介绍了StackTraceElement获取方法调用栈信息实例详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • SpringBoot使用itext填充pdf表单及导出pdf的流程

    SpringBoot使用itext填充pdf表单及导出pdf的流程

    由于最近开发的项目需要用到打印单据,就在网上找了一下方案,反反复复,都没有找到合适的,借鉴了网上资源,使用itext5、itext7的工具包,所以本文介绍了SpringBoot使用itext填充pdf表单及导出pdf的流程,需要的朋友可以参考下
    2024-09-09
  • 从Java到JSON一起探索Jackson的魔力

    从Java到JSON一起探索Jackson的魔力

    Jackson是一个用于处理JSON数据的开源Java库,这篇文章主要为大家介绍了Java是如何利用Jackson处理JSON数据的,感兴趣的小伙伴可以了解一下
    2023-05-05
  • SpringBoot中使用拦截器拦截跳转登录的两种实现方法

    SpringBoot中使用拦截器拦截跳转登录的两种实现方法

    拦截器(Interceptor)是Spring框架提供的一种机制,用于在请求的生命周期中插入自定义逻辑,如身份验证、日志记录等,本文将详细介绍两种在SpringBoot中使用拦截器来控制用户登录并跳转到指定页面的方法,需要的朋友可以参考下
    2024-11-11

最新评论