从事 javaweb 开发的开发者几乎都经历过这样的情况:所有接口都需要进行登录状态验证,整个系统还需统一处理中文字符编码。若在每个接口中都重复编写这些逻辑,不仅会导致代码冗余、结构混乱,而且后续需求变更时还需逐个修改,维护成本极高。此时,filter 拦截器便成为理想的解决方案。作为 servlet 规范原生支持的拦截机制,filter 能在请求抵达 servlet 之前、响应返回客户端之前执行预处理操作,是 web 层开发中不可或缺的核心组件之一。下面我们结合真实项目中高频使用的两个典型场景,深入解析 filter 的实际应用方式。

登录权限校验:后台系统最基础也最关键的拦截场景
对于管理类系统而言,“未登录不可访问”是最基本的安全要求。实现方式非常简洁:自定义一个 LoginFilter 类并实现 javax.servlet.Filter 接口,重点重写 doFilter 方法。首先从当前 HttpServletRequest 对应的 HttpSession 中尝试获取已登录用户对象;接着判断该对象是否为空——若为空,则直接通过 response.sendRedirect() 重定向至登录页,并 return 结束本次请求流程;若不为空,则调用 chain.doFilter(request, response) 将请求继续向下传递。只需将该 Filter 配置为拦截 /admin/** 或类似后台路径,即可一劳永逸地替代各 Controller 中的手动校验逻辑,大幅提升代码复用性与可维护性。

全局字符编码设置:应对 POST 请求中文乱码的经典实践
在传统 JavaWeb 或遗留项目中,表单提交(尤其是 POST 方式)常因编码不一致导致中文显示为问号或方块。此时 CharacterEncodingFilter 就派上大用场。我们可自定义一个 Filter,在 init() 方法中读取 web.xml 或配置文件中指定的字符集(如 UTF-8),然后在 doFilter() 中依次调用 request.setCharacterEncoding("UTF-8") 和 response.setContentType("text/html;charset=UTF-8"),最后再执行 chain.doFilter()。如此一次配置,全站生效,彻底规避乱码隐患。值得一提的是,Spring MVC 内置的 CharacterEncodingFilter,其底层原理也正是如此。
Filter 使用过程中的常见误区提醒
使用 Filter 时需特别注意两类高频问题:其一,Filter 实例默认以单例形式存在,因此切勿在类中声明非 final 的成员变量,否则极易引发多线程并发下的数据污染;其二,多个 Filter 的执行顺序至关重要。在 web.xml 中按声明顺序依次执行;使用 @WebFilter 注解时,默认依据类名 ASCII 码排序;而在 Spring Boot 环境下,推荐通过 FilterRegistrationBean 显式控制加载优先级,防止出现“先处理业务再校验权限”这类逻辑错位。

Filter 的本质,就是将横跨多个业务模块的共性逻辑进行横向抽取与集中管控,完美契合面向切面编程(AOP)思想和开闭原则。上述两个案例均为生产环境中久经考验的落地方案,合理运用 Filter 不仅能让核心业务代码更纯粹、更聚焦,还能显著减少重复劳动,切实提升整体开发效能。(全文约662字)

















