如何通过web.xml文件对Java Web应用进行详细配置?
- 内容介绍
- 相关推荐
本文共计1184个文字,预计阅读时间需要5分钟。
xml
什么时候必须写 web.xml
不是所有项目都需要手动写 web.xml,但以下情况绕不开:
- 使用 Servlet 2.5 或更早规范(如 WebLogic 10.3、WebSphere 7)
- 需要配置
<error-page>映射 HTTP 状态码或异常类(注解无法覆盖 404/500 全局页面) - 注册实现了
ServletContextListener的监听器且不支持@WebListener(比如某些 OSGi 容器或定制 ClassLoader) - 配置
<security-constraint>做基于角色的 URL 访问控制(@ServletSecurity支持有限) - 需要设置
<session-config>中的<cookie-config>高级属性(如httpOnly、secure、sameSite)——部分容器对注解支持不完整
web.xml 的基本结构和必填项
一个最小可用的 web.xml 必须包含根元素 <web-app>、命名空间声明和版本号。Servlet 3.0+ 推荐使用如下声明:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>myapp</display-name> </web-app>
注意点:
立即学习“Java免费学习笔记(深入)”;
-
version属性必须与使用的 Servlet 规范严格匹配,否则 Tomcat/Jetty 可能拒绝启动或静默降级 -
xsi:schemaLocation中的 XSD 地址不能随意替换为本地路径或旧版地址(如java.sun.com已失效) -
<display-name>不是必需的,但部分 IDE 和管理控制台会读取它
常见配置项写法与易错点
实际开发中最常出问题的是顺序和大小写。Servlet 规范强制要求元素按 DTD/XSD 定义顺序出现(例如 <servlet> 必须在 <servlet-mapping> 之前,<filter> 在 <filter-mapping> 之前)。
典型配置片段示例:
<servlet> <servlet-name>userServlet</servlet-name> <servlet-class>com.example.UserServlet</servlet-class> <init-param> <param-name>configFile</param-name> <param-value>/WEB-INF/user-config.properties</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>userServlet</servlet-name> <url-pattern>/api/user/*</url-pattern> </servlet-mapping> <filter> <filter-name>authFilter</filter-name> <filter-class>com.example.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>/api/*</url-pattern> </filter-mapping>
容易踩的坑:
-
<servlet-name>在<servlet>和<servlet-mapping>中必须完全一致(区分大小写) -
<url-pattern>中不能有空格,/api/user/*匹配/api/user/123,但不匹配/api/user(结尾无斜杠) -
<load-on-startup>值为负数表示不预加载;为 0 或正数时数值越小优先级越高;若多个 Servlet 设为相同值,容器决定顺序 - Filter 链顺序由
<filter-mapping>在文件中的**出现顺序**决定,不是<filter>的顺序
现代项目里还该用 web.xml 吗?
新项目优先用注解(@WebServlet、@WebFilter、@WebListener)和 Java 配置(ServletContainerInitializer 或 Spring Boot 的 @Bean ServletWebServerFactory)。但别彻底抛弃 web.xml:
- 它仍是调试容器行为的“真相源”:当注解没生效时,看容器日志是否加载了
web.xml,能快速判断是规范版本问题还是扫描失败 - 某些企业防火墙或安全审计要求所有入口点必须显式声明在 XML 中(禁止运行时动态注册)
- 混合部署时(如遗留 Filter + 新注解 Servlet),
web.xml的 Filter 仍会参与链,顺序需人工协调
最麻烦的其实是版本混用:比如用了 @WebServlet(urlPatterns = "/test"),但 web.xml 里又声明了同名 <servlet>,Tomcat 会报 Duplicate servlet name 错误——这种冲突往往在集成测试阶段才暴露。
本文共计1184个文字,预计阅读时间需要5分钟。
xml
什么时候必须写 web.xml
不是所有项目都需要手动写 web.xml,但以下情况绕不开:
- 使用 Servlet 2.5 或更早规范(如 WebLogic 10.3、WebSphere 7)
- 需要配置
<error-page>映射 HTTP 状态码或异常类(注解无法覆盖 404/500 全局页面) - 注册实现了
ServletContextListener的监听器且不支持@WebListener(比如某些 OSGi 容器或定制 ClassLoader) - 配置
<security-constraint>做基于角色的 URL 访问控制(@ServletSecurity支持有限) - 需要设置
<session-config>中的<cookie-config>高级属性(如httpOnly、secure、sameSite)——部分容器对注解支持不完整
web.xml 的基本结构和必填项
一个最小可用的 web.xml 必须包含根元素 <web-app>、命名空间声明和版本号。Servlet 3.0+ 推荐使用如下声明:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>myapp</display-name> </web-app>
注意点:
立即学习“Java免费学习笔记(深入)”;
-
version属性必须与使用的 Servlet 规范严格匹配,否则 Tomcat/Jetty 可能拒绝启动或静默降级 -
xsi:schemaLocation中的 XSD 地址不能随意替换为本地路径或旧版地址(如java.sun.com已失效) -
<display-name>不是必需的,但部分 IDE 和管理控制台会读取它
常见配置项写法与易错点
实际开发中最常出问题的是顺序和大小写。Servlet 规范强制要求元素按 DTD/XSD 定义顺序出现(例如 <servlet> 必须在 <servlet-mapping> 之前,<filter> 在 <filter-mapping> 之前)。
典型配置片段示例:
<servlet> <servlet-name>userServlet</servlet-name> <servlet-class>com.example.UserServlet</servlet-class> <init-param> <param-name>configFile</param-name> <param-value>/WEB-INF/user-config.properties</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>userServlet</servlet-name> <url-pattern>/api/user/*</url-pattern> </servlet-mapping> <filter> <filter-name>authFilter</filter-name> <filter-class>com.example.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>/api/*</url-pattern> </filter-mapping>
容易踩的坑:
-
<servlet-name>在<servlet>和<servlet-mapping>中必须完全一致(区分大小写) -
<url-pattern>中不能有空格,/api/user/*匹配/api/user/123,但不匹配/api/user(结尾无斜杠) -
<load-on-startup>值为负数表示不预加载;为 0 或正数时数值越小优先级越高;若多个 Servlet 设为相同值,容器决定顺序 - Filter 链顺序由
<filter-mapping>在文件中的**出现顺序**决定,不是<filter>的顺序
现代项目里还该用 web.xml 吗?
新项目优先用注解(@WebServlet、@WebFilter、@WebListener)和 Java 配置(ServletContainerInitializer 或 Spring Boot 的 @Bean ServletWebServerFactory)。但别彻底抛弃 web.xml:
- 它仍是调试容器行为的“真相源”:当注解没生效时,看容器日志是否加载了
web.xml,能快速判断是规范版本问题还是扫描失败 - 某些企业防火墙或安全审计要求所有入口点必须显式声明在 XML 中(禁止运行时动态注册)
- 混合部署时(如遗留 Filter + 新注解 Servlet),
web.xml的 Filter 仍会参与链,顺序需人工协调
最麻烦的其实是版本混用:比如用了 @WebServlet(urlPatterns = "/test"),但 web.xml 里又声明了同名 <servlet>,Tomcat 会报 Duplicate servlet name 错误——这种冲突往往在集成测试阶段才暴露。

