尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
过滤器(Filter)和 拦截器(Interceptor)
一、引言在开发过程中我们经常会遇到 过滤器(Filter) 和 拦截器(Interceptor)找个也是面试中容易被问道的一个问题两者的使用和作用又颇为相似是个容易被大家混淆的问题在此总结下希望能对大家有所帮助。二、Filter 过滤器介绍Filter定义Filter是sun公司中servlet2.3后增加的一个新功能在javaEE中定义了一个接口 javax.servlet.Filter来描述过滤器。Filter可以认为是Servlet的一种“加强版”它主要用于对用户请求进行预处理也可以对HttpServletResponse进行后处理是个典型的处理链。Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序.它依赖于servlet容器,在实现上基于函数回调,它可以对几乎所有请求进行过滤。Filter也可以对用户请求生成响应这一点与Servlet相同但实际上很少会使用Filter向用户请求生成响应。它是随你的web应用启动而启动的只初始化一次以后就可以拦截相关请求只有当你的web应用停止或重新部署的时候才销毁。Filter工作原理Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序其工作原理是只要你在web.xml文件配置好要拦截的客户端请求它都会帮你拦截到请求此时你就可以对请求或响应(Request、Response)统一处理等。使用Filter完整的流程是Filter对用户请求进行预处理接着将请求交给Servlet进行处理并生成响应最后Filter再对服务器响应进行后处理。当服务器启动会创建Filter对象并调用init方法只调用一次。当访问资源路径与Filter的拦截路径匹配会执行Filter中的doFilter方法当服务器关闭时会调用Filter的destroy方法来进行销毁操作。Filter应用场景在过滤器中修改字符编码CharacterEncodingFilter、在过滤器中修改HttpServletRequest的一些参数XSSFilter(自定义过滤器)如过滤低俗文字、危险字符、敏感词过滤、响应信息压缩、控制权限、控制转向、做一些业务逻辑判断等Filter代码实战public class TestFilter implements Filter { Override public void init(FilterConfig filterConfig) throws ServletException { //对filter进行一个初始化 } Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { //doFilter()前的代码是对用户请求进行预处理 System.out.println(我是Filter,执行filterChain.doFilter之前。); //执行Filter链中的下一个Filter filterChain.doFilter(request, response); //doFilter()后的代码是对用户请求进行后处理 System.out.println(我是Filter,执行filterChain.doFilter之后。); } Override public void destroy() { //对filter进行一个销毁 } }配置方式1 在web-xml 中进行配置filter description测试过滤器/description filter-nameTestFilter/filter-name filter-classcom.test.filtes.TestFilter/filter-class /filter filter-mapping filter-nameTestFilter/filter-name url-pattern/*/url-pattern /filter-mapping配置方式2通过WebFilter注解配置WebFilter(urlPatterns /test001) public class TestFilter1 implements Filter { Override public void init(javax.servlet.FilterConfig filterConfig) throws ServletException { System.out.println(TestFilter1 init); } Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //在DispatcherServlet之前执行 System.out.println(doFilter before); filterChain.doFilter(servletRequest, servletResponse); // 在视图页面返回给客户端之前执行但是执行顺序在Interceptor之后 System.out.println(doFilter after); } Override public void destroy() { System.out.println(TestFilter destroy); } } //2.在启动类添加ServletComponentScan SpringBootApplication ServletComponentScan public class TestbootApplication { public static void main(String[] args) { SpringApplication.run(TestbootApplication.class, args); } }PS: 多个filter 实现WebFilter难以控制filter 的过滤顺序与其包名和文件名有关慎用。配置方式3 通过Bean来配置//1.初始化Filter Component public class TestFilter2 implements Filter{ Override public void init(javax.servlet.FilterConfig filterConfig) throws ServletException { System.out.println(Filter2 init); } Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //在DispatcherServlet之前执行 System.out.println(doFilter2 before); filterChain.doFilter(servletRequest, servletResponse); // 在视图页面返回给客户端之前执行但是执行顺序在Interceptor之后 System.out.println(doFilter2 after); } Override public void destroy() { System.out.println(Filter2 destroy); } } Component public class TestFilter3 implements Filter{ Override public void init(javax.servlet.FilterConfig filterConfig) throws ServletException { System.out.println(Filter3 init); } Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //在DispatcherServlet之前执行 System.out.println(doFilter3 before); filterChain.doFilter(servletRequest, servletResponse); // 在视图页面返回给客户端之前执行但是执行顺序在Interceptor之后 System.out.println(doFilter3 after); } Override public void destroy() { System.out.println(Filter3 destroy); } } //2.注册到config Configuration public class FilterConfig { Bean public FilterRegistrationBean testFilter3RegistrationBean() { FilterRegistrationBean registration new FilterRegistrationBean(new TestFilter2()); registration.addUrlPatterns(/hello world); registration.setOrder(1); // 值越小越靠前此处配置有效 return registration; } Bean public FilterRegistrationBean testFilter4RegistrationBean() { FilterRegistrationBean registration new FilterRegistrationBean(new TestFilter3()); registration.addUrlPatterns(/hello world); registration.setOrder(2); return registration; } }三、Interceptor 拦截器介绍只针对spring介绍Interceptor 定义拦截器Interceptor和Servlet无关它依赖于Web框架在SpringMVC中就依赖于SpringMVC框架由SpringMVC框架实现。在Struts2中同理它是一种可以让你在Action执行之前和Result执行之后进行一些功能处理的机制。在实现上,基于Java的反射机制属于面向切面编程AOP的一种运用。可以用于在某个方法或者字段被访问之前进行拦截然后在之前或者之后加入某些统一的处理方法。就是在action的前、后、甚至抛出异常时进行处理比如动态代理就是拦截器的简单实现。拦截器将很多service或者Controller中共有的行为提炼出来在某些方法执行的前后执行提炼为通用的处理方式让被拦截的方法都能享受这一共有的功能让代码更加简洁同时当共有的功能需要发生调整、变动的时候不必修改很多的类或者方法只要修改这个拦截器就可以了可复用性很强。SpringMVC的拦截器基于HandlerInterceptor接口来实现所以只要实现HandlerInterceptor接口或者继承它的实现类。Interceptor 工作原理拦截器的实现分为两步第一步创建一个普通的拦截器实现 HandlerInterceptor 接口并重写接口中的相关方法第二步将上一步创建的拦截器加入到 Spring Boot 的配置文件中。preHandler(HttpServletRequest request, HttpServletResponse response, Object handler)方法在请求处理之前被调用。如果已经是最后一个 Interceptor 的时候就会调用当前请求的 Controller 方法。postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)方法在当前请求处理完成之后所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法需要在当前对应的 Interceptor 类的 preHandle 方法返回值为 true 时才会执行。顾名思义该方法将在整个请求结束之后也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理Interceptor 应用场景日志记录记录请求操作日志(用户ip,访问时间等)权限检查判断用户是否有权限访问资源,如校验token 日志记录性能监控记录请求-响应时间preHandle记录开始时间afterCompletion记录结束时间开始时间相减去结束时间登录验证判断用户是否登录sign校验封禁校验等处理cookie主题国际化本地化等filter可以实现的功能intercepter基本上都能实现Interceptor 代码实战配置方式1 在springmvc.xml 中进行配置public class BaseInterceptor implements HandlerInterceptor{ public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(Before...); System.out.println(返回true继续执行,返回false则结束请求); return true; } public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(渲染试图前,action执行后...); } public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) System.out.println(整个请求结束之后进行资源清理等); }mvc:interceptors !-- 如果直接配置bean,代表对所有请求都拦截 -- bean namebaseInterceptor classcom.test.interceptor.BaseInterceptor / mvc:interceptor !-- /**拦截所有/*拦截一层目录结构请求 -- mvc:mapping path/**/ !-- 不拦截的请求 -- mvc:exclude-mapping path/testRequestEntity/ !-- 自定义的拦截器引用 -- ref beanbaseInterceptor/ref /mvc:interceptor mvc:interceptors/配置方式2 WebConfig将拦截器注册添加到拦截器链/** * 自定义拦截器 */ Component public class MyInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 统一拦截查询token) String token request.getHeader(token); if(StringUtils.isEmpty(token)){ // return false; } System.out.println(preHandle方法在控制器的处理请求方法调用之后解析视图之前执行); return true; // 返回 true: 正常执行 false:该请求停止向下运行 } Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable ModelAndView modelAndView) throws Exception { System.out.println(postHandle方法在控制器的处理请求方法调用之后解析视图之前执行); } Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable Exception ex) throws Exception { System.out.println(Time Taken afterCompletion ); } }Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor()).addPathPatterns(/**); // .excludePathPatterns(/user/get)/.addPathPatterns(). 可以排除和指定设置 } Bean public MyInterceptor myInterceptor() { return new MyInterceptor(); } }四、过滤器(Filter)和拦截器(Interceptor) 、servlet、controller的执行顺序五、过滤器(Filter)和拦截器(Interceptor)区别过滤器(Filter)和拦截器(Interceptor)区别过滤器(Filter)拦截器(Interceptor)总结定义位置Filter定义在java.servlet包下接口HandlerInterceptor定义在org.springframework.web.servlet包下配置位置配置在web.xml中配置在springmvc.xml中作用位置Filter在只在 Servlet 前后起作用Filter 通常不考虑servlet 的实现拦截器能够深入到方法前后、异常抛出前后等因此拦截器的使用具有更大的弹性。允许用户介入hook into请求的生命周期在Spring构架的程序中要优先使用拦截器。几乎所有 Filter 能够做的事情 interceptor 都能够轻松的实现使用范围Filter 是 Servlet 规范规定的而拦截器既可以用于Web程序也可以用于Application、Swing程序中。遵循规范Filter 是遵循 Servlet 规范而拦截器是在 Spring容器内的是Spring框架支持的。与spring关系Filter 不能够使用 Spring 容器资源Interceptor 是被 Spring 调用Spring 中使用 interceptor 更容易调用方Filter 是被 Server(like Tomcat) 调用Interceptor 是被 Spring 调用因此 Filter 总是优先于 Interceptor 执行实现方式Filter 基于函数回掉Interceptor基于java反射
RELATED

相关推荐

Spring Boot、Spring Cloud实现原理

Spring Boot、Spring Cloud实现原理

Spring,Srping Boot ,Srping Cloud三者的出现时间极其发展关系Spring -> Srping Boot -> Srping Cloud下面我们浅析一下三者的发展历程及其原理。Spring什么是springSpring框架是Java平台上的一种开源应用框架,提供具有控制反转特性的容…

📅 2026/9/30 8:20:04
lsblk Command in Linux: Syntax, Options  Practical Examples (Block Devices)

lsblk Command in Linux: Syntax, Options Practical Examples (Block Devices)

lsblk — quick reference Default listing Show the block-device tree with name, size, type, and mount points — no root required. When to useCommandDefault tree of all block deviceslsblkLimit output to one disk and its childrenlsblk /dev/sdaList format (…

📅 2026/9/30 8:26:48
前端:常见字符编码全方位解析(ASCII/GB系列/UTF系列/多国编码)

前端:常见字符编码全方位解析(ASCII/GB系列/UTF系列/多国编码)

在前端开发中,字符编码是中文乱码、接口异常、文件解析错误、页面显示异常的核心根源之一。很多开发者仅会简单配置 UTF-8,却不懂各类编码的底层差异、适用边界与兼容问题。本文在原有编码对照表基础上全面迭代升级,补充编码底层原理、核心区…

📅 2026/10/13 16:24:14
MORE NEWS

更多资讯

📰

Mac本地部署Qwen-Image-2.1:UMA架构下的MLX实战指南

1. 为什么在 Mac 上跑 Qwen-Image-2.1 不是“试试看”,而是要重新理解本地 AI 图像理解的边界Qwen-Image-2.1 是通义实验室发布的多模态大模型,它不是简单的“图像识别”工具,而是一个能同时理解图文语义、执行复杂推理、支持多轮对话式图像分…

📰

Python俄罗斯方块:位运算+状态机+帧同步的硬核实现

简介:这是一份基于Python实现的经典俄罗斯方块游戏源码资源,面向编程初学者与Pygame入门学习者,帮助理解游戏主循环、碰撞检测、方块旋转与消行逻辑等核心机制。资源包共4个文件,包含1个主程序脚本(.py)、2…

📰

基于springboot医院办公室信息系统的设计与实现

医院办公室信息系统选题背景与意义 随着我国医疗卫生体制改革的不断深化以及信息化建设的持续推进,医院作为医疗服务体系的核心组成部分,其管理效率和服务质量直接关系到患者就医体验与医疗资源的合理配置。在传统管理模式下,医院办公室日常事…

📰

基于LSTM算法的景区评论情感分析及应用系统

景区评论情感分析系统选题背景与意义 随着互联网技术的迅猛发展和社交媒体平台的广泛普及,游客在出行过程中越来越倾向于通过在线平台分享旅行体验。无论是旅游网站如携程、马蜂窝,还是社交平台如微博、小红书、抖音,用户生成内容&#xff08…

📰

VC6.0下编译jsoncpp:老工程接入JSON解析的完整指南

简介:面向VC6.0开发者的jsoncpp类库项目源代码包,专门解决官方源码未提供老版本工程文件、直接在VC6中无法编译的问题。资源在官方代码基础上补齐dsp/dsw等工程配置,并完成编译选项调整,实测通过且已投入项目运行,适合…

📰

YAML声明式配置虚拟机,打造可复现的团队开发环境

最近帮一个朋友梳理本地开发环境,他抱怨最多的就是“新电脑到手,光装环境就折腾两天”。数据库、缓存、消息队列、微服务依赖,一个个手动装,版本还对不上。这其实是很多开发者的真实痛点:开发环境太脆弱,换…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬