filter 必须先于 filter-mapping 定义,否则容器启动抛 illegalargumentexception;filter-name 大小写必须严格一致;init-param 只能在 filter 块内生效,放错位置将静默失效。

filter 在 web.xml 里必须先于 filter-mapping 定义
否则 Tomcat、Jetty 等容器启动时直接抛 java.lang.IllegalArgumentException: Filter not found。XML 解析是顺序执行的,filter-mapping 引用的 filter-name 必须已在前面的 filter 块中声明过。
常见错误现象:应用能编译、能打包,但一启动就报错,日志里找不到具体哪个 filter 没定义——其实是因为引用在前、定义在后。
-
filter块写在filter-mapping块之前,顺序不能颠倒 - 多个
filter之间可以任意排序,但每个都必须出现在各自filter-mapping之前 - 不支持 forward 引用,XML 不是 Java,没有“声明提升”机制
filter-name 必须严格大小写一致且完全匹配
web.xml 是区分大小写的 XML 文件,filter-name 在 filter 和 filter-mapping 中拼错一个字母或大小写不对,就会导致过滤器不生效,且通常无报错——请求悄悄绕过,调试时极难发现。
使用场景:比如你配了 <filter-name>AuthFilter</filter-name>,但在 filter-mapping 里写成 <filter-name>authFilter</filter-name>,这个映射就失效。
立即学习“Java免费学习笔记(深入)”;
- 复制粘贴时注意光标位置,容易漏掉末尾字母或空格
- IDE 一般不会校验跨块匹配,别依赖自动提示
- 建议在
filter块里写完立刻补上对应的filter-mapping,避免来回滚动核对
url-pattern 匹配顺序由容器决定,但配置顺序影响同名 filter 的链式调用
多个 filter-mapping 映射到同一个 filter-name 时,它们的执行顺序就是 filter-mapping 在 XML 中出现的先后顺序;而不同 filter-name 之间的执行顺序,则取决于所有 filter-mapping 的 url-pattern 匹配结果和容器实现(Servlet 规范只保证“匹配路径最长者优先”,不保证同级 pattern 的声明顺序)。
性能影响:过多的 filter-mapping 块会增加容器启动时的 pattern 解析开销,但运行时影响几乎为零。
- 想控制 AFilter → BFilter → Servlet 的执行链,就让 A 的 mapping 出现在 B 的 mapping 之前(且它们 pattern 能同时匹配该请求路径)
- 避免用
/*和/api/*同时映射同一 filter,可能引发重复执行 - Tomcat 9+ 对通配符匹配做了优化,但旧版本(如 7.x)对
*.do和/path/*混用时行为不一致
init-param 在 filter 定义块内才有效,放错位置会被忽略
init-param 只能作为 filter 元素的子元素,如果误写在 filter-mapping 里,XML 虽能解析通过,但参数根本不会传给 Filter 实例——getInitParameter("xxx") 返回 null,且无任何警告。
容易踩的坑:复制其他配置时,把整个 <init-param>...</init-param> 块粘贴到了 filter-mapping 下面,看着结构差不多,实际已失效。
- 检查点:init-param 的父节点必须是
filter,不是filter-mapping或web-app - IDE 的 XML Schema 校验有时不报错,得靠手动确认层级
- Filter 类中建议在
init()方法开头加日志,打印所有getInitParameterNames(),验证是否读到预期参数
最麻烦的不是写错,而是写错后没报错、没日志、请求照常走——它只是静默跳过了你的逻辑。多看一眼 filter-name 和 init-param 的位置,比重启三次服务器省时间。










