目录
一、概念
1.1 概念
Tomcat 是一个 Web 容器(Web Container),更精确地说,它主要是一个 Servlet 容器(Servlet Container)。它实现了 Java Servlet、JSP(JavaServer Pages)、WebSocket 等规范。
Web 应用服务器 (Web Server):它能处理 HTTP 请求,将静态内容(如 HTML、图片)返回给客户端(如浏览器)。在这方面,它类似于 Nginx 或 Apache HTTP Server,但能力远不止于此。
Servlet 容器 (Servlet Container):这是它的核心身份。它实现了 Java Servlet、JSP (JavaServer Pages) 和 EL (Expression Language) 等 Java EE(现 Jakarta EE)规范。它的主要工作是管理和执行编写的 Servlet 和 JSP 程序。核心职责:
生命周期管理:负责创建、初始化、调用服务和最终销毁Servlet实例。你不用自己写
main
方法来启动它,容器会处理这一切。网络通信:监听一个网络端口(通常是8080),处理进来的HTTP请求(请求行、请求头、请求体等),并将这些请求封装成标准的Java对象(
HttpServletRequest
)。会话管理:自动为不同的用户创建和管理会话(
HttpSession
),例如使用Cookie或URL重写来跟踪用户状态。资源管理:提供了一种统一的方式來读取Web应用的文件(如配置文件、图片等),通常通过
ServletContext
对象。将响应返回给客户端:获取你的Servlet代码生成的响应(写入
HttpServletResponse
对象),并将其格式化成正确的HTTP响应报文,发送回浏览器。
因此,Tomcat 更像是一个 “Java Web 应用运行时环境”,专门用来运行用 Java 技术栈(Servlet/JSP)开发的 Web 应用程序。
1.2 核心能力
处理 HTTP 请求:Tomcat 监听端口(默认8080),接收、解析HTTP请求,并将请求交给对应的Servlet处理。
Servlet/JSP 生命周期管理:负责加载、初始化、执行和销毁 Servlet 和 JSP 文件。
会话(Session)管理:提供HTTP会话管理机制,如通过Cookie或URL重写来跟踪用户会话状态。
安全性:支持基于配置文件的认证和授权(如基本认证、表单认证)。
静态资源服务:可以像普通Web服务器一样提供HTML、图片、CSS、JS等静态文件。
轻量级与易用性:部署简单,启动快速,资源占用相对较小,是开发和部署中小型Web应用的首选。
1.3 Tomcat的限制
Tomcat 的边界就在于它 仅仅 是一个 Web 容器,而不是一个 完整的 Java EE(现 Jakarta EE)应用服务器。这意味着它缺少对很多企业级功能的原生支持:
不支持 EJB(核心限制):这是最关键的一点。Tomcat 不能 运行 EJB(Enterprise JavaBeans)。EJB 需要的是一个 EJB 容器,而 Tomcat 没有内置这个容器。
EJB(Enterprise JavaBeans) 是 Java EE(Jakarta EE)平台中用于开发分布式、事务性、可扩展且安全的服务器端业务组件的标准架构。EJB 旨在将开发者从编写处理事务、安全性、并发、远程访问等底层基础设施代码中解放出来。开发者只需专注于业务逻辑,而由 EJB 容器(运行在应用服务器内)来提供这些复杂的“企业级”服务。
有限的支持服务:
JMS(Java Message Service):Tomcat 不提供原生的JMS消息代理功能。你需要集成外部消息中间件(如 ActiveMQ、RabbitMQ)并手动管理连接工厂等资源。
JTA(Java Transaction API):Tomcat 没有内置的全局事务管理器。它支持本地事务(如JDBC事务),但如果你需要管理跨多个数据库或资源(如数据库+消息队列)的分布式事务,则需要集成第三方JTA实现(如 Bitronix, Atomikos),配置复杂。
JCA(Java EE Connector Architecture):不支持连接企业信息系统(EIS)的标准架构。
完整的JPA persistence:虽然可以通过集成Hibernate等ORM框架来使用JPA,但Tomcat本身不提供容器管理持久化(CMP)等高级功能。
管理和监控工具相对简单:相比WebLogic、WebSphere等全功能应用服务器,Tomcat提供的管理和监控功能(如JMX)较为基础。
Tomcat 非常适合基于 Servlet/JSP 的 Web 应用程序。 如果你的应用主要是处理HTTP请求、展示页面、使用Spring/Spring Boot等轻量级框架(它们自己提供了事务管理、依赖注入等功能来弥补Tomcat的不足),那么Tomcat是完美选择。
但是, 如果你的应用需要完整的、开箱即用的企业级功能,如EJB、分布式事务、JMS消息队列,那么你需要一个功能完整的应用服务器(如 WildFly, JBoss EAP, IBM WebSphere, Oracle WebLogic)。
1.4 核心组件
这些组件都在 conf/server.xml
文件中进行配置。
Server:代表整个 Tomcat 实例(一个 JVM 进程)。它是顶级元素。Server包含多个Service。
Service:一个 Service 包含一个 Connector 和一个 Engine,将它们组合在一起提供服务。
Connector (连接器):负责接收外部请求。最常用的是:
HTTP/1.1 Connector:默认监听 8080 端口,处理 HTTP 请求。
AJP Connector:监听 8009 端口,使用 AJP 协议与前面的 Web 服务器(如 Apache HTTPD)通信,通常用于集成和负载均衡。
每个 Connector 都会创建一个请求队列,并管理一个线程池来处理连接。
Engine (引擎):是一个请求处理管道,代表整个 Servlet 引擎。它接收来自 Connector 的请求,进行解析后,将其匹配并分发到正确的 Host。
Host (虚拟主机):代表一个虚拟主机,允许在同一 Tomcat 实例上部署多个不同域名的应用(如
app1.com
和app2.com
)。默认的 Host 是localhost
。Context (上下文):这是最重要的概念之一,一个 Context 对应一个 Web 应用程序(一个
.war
文件或一个包含项目结构的目录)。它配置了应用的路径、资源等。
核心功能模块的别名:
Catalina:Tomcat 的 Servlet 容器 的实现名称。它包含了上述的 Engine, Host, Context 等组件。当我们说 “Tomcat 作为一个 Servlet 容器” 时,指的就是 Catalina。负责解析Tomcat的配置文件server.xml,以此来创建服务器Server组件并进行管理。
Coyote:Tomcat 的 HTTP 连接器 的实现名称。它负责以 HTTP 协议与客户端通信。
Jasper:Tomcat 的 JSP 引擎。它负责将 JSP 文件编译成对应的 Java Servlet 源码(
.java
),然后再编译成字节码(.class
)并加载执行。Cluster:提供会话复制和集群功能,用于实现高可用和负载均衡。
1.5 请求处理流程(简化)
浏览器 HTTP 请求 -> Coyote (监听 8080) -> Catalina Engine -> 匹配 Host -> 匹配 Context (/yourApp) -> 根据 web.xml 匹配 Servlet -> 执行您的业务代码 -> 返回响应 -> 浏览器
二、基本操作
2.1 下载与安装
官网下载:https://tomcat.apache.org/
解压即用,无需安装。需要系统有 JDK。
2.2 启动与停止
Linux/Mac:
./bin/startup.sh
和./bin/shutdown.sh
Windows:
bin\startup.bat
和bin\shutdown.bat
2.3 访问测试
启动后,在浏览器访问 http://localhost:8080
,即可看到 Tomcat 的欢迎页面。
2.4 部署应用
最简单方式:将打包好的
your-app.war
文件复制到webapps/
目录下,Tomcat 会自动解压并部署。应用上下文路径通常是/your-app
(不含.war
后缀)。修改配置:在
conf/server.xml
中配置<Context>
元素,或是在conf/Catalina/localhost/
下创建独立的 XML 文件来定义应用路径和位置。
三、目录结构与核心配置文件
3.1 目录结构
目录/文件 | 类型 | 主要功能与核心文件说明 | |
---|---|---|---|
bin/ |
目录 | 二进制脚本目录:包含所有启动、停止和其他管理Tomcat服务器的脚本和可执行文件。 | |
文件 | startup.bat / startup.sh |
Windows/Linux 下的启动脚本。 | |
文件 | shutdown.bat / shutdown.sh |
Windows/Linux 下的停止脚本。 | |
文件 | catalina.bat / catalina.sh |
核心控制脚本,被上述脚本调用。 | |
文件 | setenv.bat / setenv.sh |
(需自建)用于设置自定义环境变量(如JVM参数)。需要设置JVM参数(如内存设置 -Xms 、-Xmx )时,应创建 bin/setenv.sh (或 setenv.bat )文件,而不是直接修改 catalina.sh ,以便于升级和维护。 |
|
conf/ |
目录 | 配置文件目录:包含Tomcat的全局配置文件,修改后通常需要重启才能生效。在修改 conf/ 目录下的任何文件前,最好先进行备份。 |
|
文件 | server.xml |
主配置文件。可修改服务器端口、配置虚拟主机、连接器等。 | |
文件 | web.xml |
所有Web应用的默认部署描述符。配置默认会话超时、MIME类型等。 | |
文件 | context.xml |
所有Web应用的默认上下文配置。常用于配置全局数据源等JNDI资源。 | |
文件 | tomcat-users.xml |
用户认证文件。配置访问Manager和Host Manager应用的用户和角色。 | |
文件 | catalina.policy |
Java安全策略文件,配置Tomcat以安全模式运行时的权限。 | |
lib/ |
目录 | 共享库目录:存放Tomcat服务器运行所需及所有Web应用可访问的JAR文件(如Servlet API)。 | |
说明 | 通常将数据库驱动等通用JAR包放在此处,但应用自身的库应放在其 WEB-INF/lib 中。 |
||
logs/ |
目录 | 日志文件目录:存放Tomcat运行时生成的各种日志文件,是排查故障的首要位置。 | |
文件 | catalina.out / catalina.{date}.log |
主要的应用日志,包含未捕获的异常和System.out/err 输出。遇到问题时,首先查看这个文件 |
|
文件 | localhost_access_log.{date}.txt |
HTTP访问日志,记录所有HTTP请求的详细信息。 | |
文件 | localhost.{date}.log |
Tomcat内部引擎日志。 | |
webapps/ |
目录 | Web应用部署目录:最核心的目录,用于存放需要部署的Web应用程序(WAR包或解压后的文件夹)。生产环境中,应及时删除或禁用 webapps/ 下的 docs , examples 等示例应用,并为 manager 应用配置强密码。 |
|
说明 | 部署方式:1. 将WAR包复制到此目录。 2. 将符合WAR结构的文件夹复制到此目录。 | ||
文件夹 | ROOT/ |
根应用。访问 http://localhost:8080/ 时显示的内容。 |
|
文件夹 | manager/ / host-manager/ |
用于管理和监控Tomcat的Web控制台应用。 | |
work/ |
目录 | 工作目录:存放Tomcat运行时的临时文件,例如JSP编译后生成的Java源文件和Class文件。 | |
说明 | 清空此目录可强制Tomcat重新编译JSP,常用于解决JSP缓存引起的疑难问题。 | ||
temp/ |
目录 | 临时文件目录:被JVM用于存放应用程序运行过程中产生的临时文件(如文件上传的临时文件)。 |
可以把Tomcat想象成一个预装好的房子:
bin/
- 大门和电闸:从这里进出(启动/停止)。conf/
- 房子的总设计蓝图:决定了房子的结构、规则和配置。lib/
- 共享的工具库:所有房间都可以使用的公共工具。logs/
- 监控录像和日志:记录房子里发生的一切。webapps/
- 一个个房间:你自己装修布置的地方(部署你的Web应用)。work/
- 每个房间的装修工作间:存放装修时用的临时材料和图纸(JSP编译文件)。temp/
- 公共垃圾桶:存放临时垃圾,会被定期清理。
3.2 核心配置文件
配置文件 | 主要作用 | 修改频率 | 生产环境建议 |
---|---|---|---|
server.xml |
定义服务器架构、连接器、虚拟主机。 | 低 | 仔细规划端口和虚拟主机。启用访问日志(AccessLogValve )。 |
web.xml |
为所有应用设置默认值(会话超时、MIME类型等)。 | 极低 | 通常保持默认即可,特定设置应在应用自身的 web.xml 中配置。 |
context.xml |
配置所有应用共享的资源和全局设置(如JNDI数据源)。 | 中 | 集中管理数据库连接池等资源的理想位置。 |
tomcat-users.xml |
管理用户认证和授权,用于访问管理控制台。 | 低 | 务必修改默认密码! 删除或注释掉默认示例用户。严格分配角色。 |
3.2.1 conf/server.xml
server.xml
:主配置文件,决定 Tomcat 的整体结构和组件。
Tomcat 的组件是分层嵌套的,理解这个层次关系是看懂 server.xml
的关键。基本结构如下:
Server
→Service
→Connector(s)
&Engine
→Host
→Context
Server: 代表整个 Tomcat 实例(一个 JVM 进程),是顶级组件。
Service: 将一个或多个
Connector
与一个Engine
绑定在一起,组成一个完整的服务单元。Connector: 处理外部客户端的连接和通信(如 HTTP, AJP)。
Engine: 处理所有来自
Connector
的请求,是请求处理的入口。Host: 代表一个虚拟主机,用于将请求映射到特定的 Web 应用(
Context
)。Context: 代表一个独立的 Web 应用程序。
server.xml示例:
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<!-- ==================== 线程池配置 (可选) ==================== -->
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="200"
minSpareThreads="10"
maxQueueSize="100"
prestartminSpareThreads="true"/>
<!-- ==================== HTTP 连接器 (NIO) ==================== -->
<Connector executor="tomcatThreadPool"
port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443"
maxConnections="10000"
acceptCount="100"
compression="on"
compressionMinSize="1024"
compressableMimeType="text/html,text/xml,text/css,text/javascript,application/json"
enableLookups="false"
URIEncoding="UTF-8"
server="Unknown" />
<!-- ==================== AJP 连接器 (通常用于集成前端Web服务器如Apache HTTPD或Nginx) ==================== -->
<!-- 生产环境中若Tomcat直接对外,或使用Nginx反向代理(通常用HTTP代理而非AJP),可考虑注释或删除AJP连接器 -->
<!--
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443"
secretRequired="true"
secret="YourStrongAJPSecret" />
-->
<!-- ==================== SSL/TLS 连接器 (HTTPS) ==================== -->
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true"
scheme="https"
secure="true">
<SSLHostConfig certificateVerification="false"
protocols="TLSv1.2,TLSv1.3">
<Certificate certificateKeystoreFile="conf/keystore.jks"
certificateKeystorePassword="changeit"
type="RSA" />
</SSLHostConfig>
</Connector>
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
</Realm>
<Host name="localhost"
appBase="webapps"
unpackWARs="true"
autoDeploy="false"
deployOnStartup="true"
deployIgnore=".*\.svn/.*">
<!-- ==================== 访问日志 Valve ==================== -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b %D"
rotatable="true" />
<!-- ==================== 远程IP Valve (如果你在Tomcat前使用了反向代理,如Nginx) ==================== -->
<!--
<Valve className="org.apache.catalina.valves.RemoteIpValve"
internalProxies="192\.168\.\d{1,3}\.\d{1,3}|10\.\d{1,3}\.\d{1,3}\.\d{1,3}"
remoteIpHeader="x-forwarded-for"
proxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto" />
-->
</Host>
</Engine>
</Service>
</Server>
按以上分层讲解标签:
组件/元素 (Element) | 关键属性 (Key Attributes) | 作用与描述 |
---|---|---|
<Server> |
port |
指定 Tomcat 监听 shutdown 命令的端口。用于通过 CATALINA_HOME/bin/shutdown.sh 脚本安全关闭 Tomcat。 |
shutdown |
指定发送到上述端口以关闭 Tomcat 的魔法字符串命令。 | |
<Listener> |
className |
指定监听器类的全限定名。用于在 Tomcat 生命周期的特定事件(如启动、停止)触发时执行代码。例如: JreMemoryLeakPreventionListener 防止 JRE 内存泄漏。 |
组件/元素 (Element) | 关键属性 (Key Attributes) | 作用与描述 |
---|---|---|
<Service> |
name |
为服务提供一个名称,主要用于日志记录。 |
组件/元素 (Element) | 关键属性 (Key Attributes) | 作用与描述 |
---|---|---|
<Connector> (HTTP/1.1) |
port |
必填。Connector 监听的 TCP 端口号(如 8080, 8443)。 |
protocol |
指定协议处理器。通常使用 HTTP/1.1 来自动选择基于 NIO 或 APR 的高性能实现。 |
|
connectionTimeout |
连接建立后,等待客户端发送请求的超时时间(毫秒)。 | |
redirectPort |
如果该 Connector 不支持 SSL,但收到了 SSL 请求,将自动重定向到此端口(通常为 8443)。 | |
maxThreads |
性能调优关键。处理请求的最大线程数,决定了 Tomcat 的并发处理能力。 | |
acceptCount |
当所有处理线程都在忙碌时,传入连接请求队列的最大长度。 | |
compression |
是否对响应数据进行 GZIP 压缩(on /off ),可节省带宽。 |
|
<Connector> (AJP) |
protocol |
设置为 AJP/1.3 ,用于与前置的 HTTP 服务器(如 Apache HTTPD)集成。 |
secret |
设置 AJP 连接的密码,增强安全性(与 Apache 的 secret 配置匹配)。 |
|
<Connector> (HTTPS/SSL) |
protocol |
同上,通常为 HTTP/1.1 。 |
port |
通常为 8443 。 |
|
SSLEnabled |
设置为 true 以启用 SSL/TLS。 |
|
keystoreFile |
指定服务器证书密钥库(Keystore)文件的路径。 | |
keystorePass |
密钥库的密码。 | |
ciphers |
指定启用的加密套件,用于控制安全强度和兼容性。 | |
<SSLHostConfig> |
(Tomcat 8.5+ 推荐方式) 用于更现代地配置 SSL,替代上述部分 SSL 属性。包含 certificate 等子元素。 |
谨慎使用 AJP:AJP 协议通常用于与 Apache HTTPD 等 Web 服务器集成。如果 Tomcat 直接面对互联网,通常不需要也不应该开启 AJP Connector,因为它本身没有加密和强认证机制,存在安全风险。
组件/元素 (Element) | 关键属性 (Key Attributes) | 作用与描述 |
---|---|---|
<Engine> |
name |
Engine 的名称,用于日志。 |
defaultHost |
必填。指定默认的虚拟主机名。如果请求的 Host 头不匹配任何配置的 Host ,则使用此主机处理。 |
|
<Host> |
name |
必填。虚拟主机的域名(如 localhost , www.example.com )。客户端请求的 Host 头必须与此匹配。 |
appBase |
必填。指定该虚拟主机的应用程序部署目录(如 webapps )。可以是绝对路径或相对于 $CATALINA_BASE 的相对路径。 |
|
autoDeploy |
是否在 Tomcat 运行时自动部署放入 appBase 目录的新应用或更新。生产环境通常设置为 false 。 |
|
unpackWARs |
是否将部署的 WAR 包解压为目录。true 利于性能但占用磁盘;false 反之。 |
|
<Valve> (在 Host 内) |
className |
类似于一个请求过滤器。AccessLogValve 是最常用的,用于记录访问日志。 |
directory |
(AccessLogValve) 访问日志文件的存放目录。 | |
pattern |
(AccessLogValve) 定义日志记录的格式(如 %h %l %u %t "%r" %s %b )。 |
|
className="org.apache.catalina.valves.ErrorReportValve" |
自定义错误页面。 | |
<Context> |
docBase |
Web 应用的路径。可以是 WAR 文件或解压后的目录路径。 |
path |
Web 应用的上下文路径。如果为空字符串 "" ,则该应用是根应用。 |
|
reloadable |
如果为 true ,Tomcat 会监视 /WEB-INF/classes/ 和 /WEB-INF/lib/ 的变化并自动重载应用。开发方便,但生产环境应设为 false 以避免性能开销。 |
|
sessionTimeout |
覆盖 web.xml 中配置的会话超时时间(分钟)。 |
避免在 server.xml 中配置 <Context>
:官方推荐将应用特定的 <Context>
配置放在 $CATALINA_BASE/conf/[enginename]/[hostname]/
目录下的独立 XML 文件中(例如 myapp.xml
)。这样更清晰,且无需重启整个 Tomcat 来应用更改(依赖 autoDeploy
)。
组件/元素 (Element) | 关键属性 (Key Attributes) | 作用与描述 |
---|---|---|
<GlobalNamingResources> |
定义全局 JNDI 资源,可供所有 Web 应用访问。 | |
<Resource> |
name |
JNDI 资源名称(如 jdbc/myDataSource )。 |
type |
资源的 Java 类全名(如 javax.sql.DataSource )。 |
|
auth |
通常为 Container ,表示由容器负责管理资源认证。 |
|
maxTotal |
(对于数据库连接池) 连接池最大活动连接数。 | |
driverClassName |
JDBC 驱动类名。 | |
url |
数据库连接 URL。 | |
<Realm> |
className |
用于配置用户认证和授权的区域。例如 JDBCRealm (数据库认证)、UserDatabaseRealm (从 conf/tomcat-users.xml 认证)。 |
3.2.2 conf/web.xml
web.xml
:全局部署描述符,为所有 Web 应用提供默认设置
Tomcat 中有 两个 web.xml
文件:
全局 web.xml (在
$CATALINA_HOME/conf/
目录下): 此文件为部署在该 Tomcat 实例上的所有 Web 应用程序提供默认的公共配置。它对所有应用生效。应用级 web.xml (在 Web 应用的
WEB-INF/
目录下): 此文件用于配置单个特定的 Web 应用程序。它的配置会覆盖全局web.xml
中的同名配置。
web.xml
是 Java Web 应用的部署描述符(Deployment Descriptor),其配置遵循 Servlet 规范。它的核心作用是将 URL 映射到特定的 Servlet、定义初始化参数、配置容器提供的各种服务。
web.xml示例:
<?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_4_0.xsd"
version="4.0">
<!-- 1. 应用基本信息 -->
<display-name>My-Production-Application</display-name>
<description>This is the production environment configuration for my application.</description>
<!-- 2. 全局初始化参数 (例如:设置Spring配置文件和Profile) -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
</param-value>
</context-param>
<!-- 强烈建议生产环境明确设置激活的Profile,便于条件化配置 -->
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>production</param-value>
</context-param>
<!-- 3. 监听器 (例如:Spring的ContextLoaderListener) -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 4. 过滤器 (Filter) 配置 -->
<!-- 4.1 字符编码过滤器 (几乎必备) -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 4.2 防止XSS攻击的过滤器 (安全增强) -->
<!-- 注意:你需要引入相应的JAR包(如OWASP ESAPI)或编写自己的XSS过滤逻辑 -->
<filter>
<filter-name>xssProtectionFilter</filter-name>
<filter-class>com.example.security.XSSProtectionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>xssProtectionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 5. Servlet 配置 -->
<!-- 5.1 Spring MVC 分发器Servlet -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<!-- 生产环境建议设置load-on-startup,保证服务启动时即初始化 -->
<load-on-startup>1</load-on-startup>
<!-- 开启异步支持(如需要) -->
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 6. 会话 (Session) 配置 -->
<session-config>
<!-- 会话超时时间(分钟)。生产环境可根据需求设置,例如30分钟 -->
<session-timeout>30</session-timeout>
<!-- Cookie配置 (Servlet 3.0+) - 生产环境应对Cookie进行安全加固 -->
<cookie-config>
<http-only>true</http-only> <!-- 防止XSS读取Cookie -->
<secure>true</secure> <!-- 仅通过HTTPS传输Cookie (生产环境必须开启) -->
<!-- <name>MY_SESSIONID</name> --> <!-- 可自定义会话Cookie名 -->
<!-- <domain>yourdomain.com</domain> --> <!-- 设置Cookie域 -->
<!-- <path>/</path> -->
</cookie-config>
<!-- 追踪模式(建议使用URL重写,而不是COOKIE,以增加兼容性,但现代浏览器已很少需要) -->
<!-- <tracking-mode>COOKIE</tracking-mode> -->
</session-config>
<!-- 7. 错误页面配置 (提供友好且信息可控的错误页面) -->
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/views/errors/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/views/errors/500.jsp</location>
</error-page>
<!-- 也可以捕获特定异常 -->
<!-- <error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/WEB-INF/views/errors/general-error.jsp</location>
</error-page> -->
<!-- 8. MIME类型映射 (如有非标准文件类型需要服务器识别) -->
<mime-mapping>
<extension>json</extension>
<mime-type>application/json</mime-type>
</mime-mapping>
<!-- 9. 欢迎文件列表 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 10. 安全配置 (声明式安全 - 通常在应用服务器中配置更常见,但也可在此定义) -->
<!-- 注意:以下为示例,具体角色和约束需根据应用调整 -->
<!--
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Resources</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login</form-login-page>
<form-error-page>/login?error</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
-->
</web-app>
配置元素 (Element) | 所属范围 | 作用描述 | 示例或备注 |
---|---|---|---|
<web-app> |
根元素 | 所有配置的根容器,定义了配置文件的版本和Schema。 | xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="4.0" |
<display-name> |
应用级 | 为Web应用提供一个可读的名称,用于管理工具(如Tomcat Manager)显示。 | <display-name>My Awesome App</display-name> |
<description> |
应用级 | 提供一段关于此Web应用的描述文本。 | <description>This app does amazing things.</description> |
<context-param> |
应用级 | 定义应用范围内的全局初始化参数,所有Servlet和JSP都可以通过 ServletContext.getInitParameter() 获取。 |
<param-name>jdbcURL</param-name><param-value>jdbc:mysql://localhost:3306/mydb</param-value> |
Servlet 相关配置 | |||
<servlet> |
应用级 | 声明一个Servlet。包含 <servlet-name> 和 <servlet-class> (或 <jsp-file> )。 |
|
↳ <servlet-name> |
应用级 | 为Servlet定义一个逻辑名称,用于在<servlet-mapping> 中引用。 |
<servlet-name>FancyServlet</servlet-name> |
↳ <servlet-class> |
应用级 | 指定Servlet对应的完整Java类名。 | <servlet-class>com.example.FancyServlet</servlet-class> |
↳ <jsp-file> |
应用级 | 指定一个JSP文件作为Servlet。 | <jsp-file>/index.jsp</jsp-file> |
↳ <init-param> |
应用级 | 定义该Servlet独有的初始化参数。可通过 ServletConfig.getInitParameter() 获取。 |
<param-name>configFile</param-name><param-value>/WEB-INF/config.xml</param-value> |
↳ <load-on-startup> |
应用级 | 控制Servlet的加载时机。值为正数时,容器在启动时即加载并初始化该Servlet(数值越小优先级越高)。 | <load-on-startup>1</load-on-startup> |
<servlet-mapping> |
应用级 | 将URL模式映射到已声明的Servlet。 | |
↳ <servlet-name> |
应用级 | 引用在 <servlet> 中定义的逻辑名称。 |
<servlet-name>FancyServlet</servlet-name> |
↳ <url-pattern> |
应用级 | 定义匹配的URL模式(如 /api/* , *.do , /foo )。 |
<url-pattern>/api/*</url-pattern> |
Filter 相关配置 | |||
<filter> |
应用级 | 声明一个过滤器(Filter)。包含 <filter-name> 和 <filter-class> 。 |
|
↳ <filter-name> |
应用级 | 为Filter定义一个逻辑名称。 | <filter-name>AuthFilter</filter-name> |
↳ <filter-class> |
应用级 | 指定Filter对应的完整Java类名。 | <filter-class>com.example.AuthFilter</filter-class> |
↳ <init-param> |
应用级 | 定义该Filter独有的初始化参数。 | |
<filter-mapping> |
应用级 | 将Filter与URL模式或Servlet关联,决定Filter对哪些请求生效。 | |
↳ <filter-name> |
应用级 | 引用在 <filter> 中定义的逻辑名称。 |
<filter-name>AuthFilter</filter-name> |
↳ <url-pattern> |
应用级 | 定义Filter要拦截的URL模式。 | <url-pattern>/secure/*</url-pattern> |
↳ <servlet-name> |
应用级 | 定义Filter要拦截的特定Servlet。 | <servlet-name>AdminServlet</servlet-name> |
Listener 配置 | |||
<listener> |
应用级 | 声明一个事件监听器(Listener)。 | |
↳ <listener-class> |
应用级 | 指定监听器对应的完整Java类名。监听器用于响应Web应用生命周期事件(如启动、关闭)和会话事件。 | <listener-class>com.example.MyContextListener</listener-class> |
会话(Session)配置 | |||
<session-config> |
应用级/全局 | 配置HTTP会话的全局设置。 | |
↳ <session-timeout> |
应用级/全局 | 指定会话默认的超时时间(分钟)。-1或负数表示永不过期。 | <session-timeout>30</session-timeout> |
MIME 类型映射 | |||
<mime-mapping> |
全局/应用级 | 将文件扩展名映射到MIME类型。 | 全局web.xml 中已包含大量常见映射。 |
↳ <extension> |
全局/应用级 | 文件扩展名(不带点)。 | <extension>pdf</extension> |
↳ <mime-type> |
全局/应用级 | 对应的MIME类型。 | <mime-type>application/pdf</mime-type> |
欢迎文件列表 | |||
<welcome-file-list> |
应用级/全局 | 当用户访问目录URL时(如 http://host/app/ ),容器按顺序查找并返回的文件列表。 |
|
↳ <welcome-file> |
应用级/全局 | 定义欢迎文件名。 | <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> |
错误页面处理 | |||
<error-page> |
应用级 | 配置特定HTTP错误代码或异常类型所对应的自定义错误页面。 | |
↳ <error-code> |
应用级 | HTTP错误代码(如404、500)。 | <error-code>404</error-code> |
↳ <exception-type> |
应用级 | Java异常的全限定类名(如 java.io.IOException )。 |
<exception-type>java.lang.Exception</exception-type> |
↳ <location> |
应用级 | 显示的错误页面路径(相对于web应用根目录)。 | <location>/error/404.html</location> |
安全相关配置 | |||
<security-constraint> |
应用级 | 定义资源的安全约束(哪些URL需要认证、需要什么角色、使用什么传输保证)。 | |
<login-config> |
应用级 | 配置Web应用的认证方式(如BASIC, DIGEST, FORM, CLIENT-CERT)。 | <auth-method>FORM</auth-method><form-login-config><form-login-page>/login.html</form-login-page><form-error-page>/login-error.html</form-error-page></form-login-config> |
<security-role> |
应用级 | 声明应用中使用的安全角色名称。 | <role-name>admin</role-name> |
3.2.3 conf/context.xml
context.xml
:全局上下文配置,定义所有 Web 应用共享的资源。一个 Context
代表一个独立的 Web 应用程序。
核心作用:context.xml
主要用于配置与应用本身密切相关的资源、参数和行为,如数据库连接池(JNDI DataSource)、会话(Session)管理、监控阀门(Valves)、初始化参数等。
与全局的 server.xml
不同,context.xml
的配置可以出现在多个位置,且优先级不同(从上到下,优先级递增):
$CATALINA_BASE/conf/context.xml
: 此文件中的配置适用于所有部署到该 Tomcat 实例的 Web 应用程序。是全局默认配置。$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default
: 适用于部署到特定虚拟主机(Host)的所有 Web 应用程序。应用特定的 XML 文件: 在
$CATALINA_BASE/conf/[enginename]/[hostname]/
目录下,创建[appname].xml
文件(例如myapp.xml
)。此文件中的配置仅适用于该特定应用。这是生产环境推荐的方式,因为它与应用解耦,无需修改server.xml
或全局context.xml
。Web 应用内部的
/META-INF/context.xml
: 打包在 WAR 文件或应用目录中。此配置随应用一起发布,适用于该应用本身。
context.xml示例:
在 $CATALINA_BASE/conf/Catalina/localhost/
下创建 myapp.xml
,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 此配置仅适用于 'myapp' 这个应用 -->
<Context>
<!-- 1. 禁用开发特性,提升性能 -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- 2. 配置数据库连接池 (JNDI DataSource) -->
<Resource name="jdbc/MyAppDS"
auth="Container"
type="javax.sql.DataSource"
username="prod_db_user"
password="very_strong_password"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://dbserver:3306/prod_db?useUnicode=true&characterEncoding=UTF-8&useSSL=true"
maxTotal="50"
maxIdle="20"
minIdle="5"
maxWaitMillis="10000"
validationQuery="SELECT 1"
testOnBorrow="true"
removeAbandonedOnBorrow="true"
removeAbandonedTimeout="60" />
<!-- 3. 配置会话Cookie为Secure和HttpOnly -->
<SessionConfig>
<cookie secure="true" httpOnly="true" />
</SessionConfig>
<!-- 4. 如果前面有反向代理,配置RemoteIpValve以获取真实客户端IP -->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for"
proxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto" />
</Context>
元素/属性 (Element/Attribute) | 作用与描述 |
---|---|
<Context> |
根元素,代表一个 Web 应用上下文。 |
path="" |
应用的上下文路径(访问路径)。例如,path="/shop" 意味着应用可通过 http://host:port/shop 访问。设置为空字符串 "" 表示将此应用设为根应用(通过 http://host:port/ 访问)。注意:在独立的应用 XML 文件中,此属性通常由文件名决定,无需在 <Context> 标签内重复指定。 |
docBase="myapp" |
Web 应用所在的位置。可以是 WAR 文件的路径(如 myapp.war )或应用程序目录的路径(如 webapps/myapp )。可以是绝对路径,也可以是相对于 $CATALINA_BASE/webapps 的相对路径。 |
reloadable="false" |
生产环境关键设置。如果设为 true ,Tomcat 会监视 /WEB-INF/classes/ 和 /WEB-INF/lib/ 的变化,并自动重新加载应用。开发环境非常方便,但生产环境会带来严重性能开销,必须设为 false 。 |
crossContext="true" |
是否允许应用通过 ServletContext.getContext() 方法获取其他 Web 应用的上下文。通常出于安全考虑设为 false 。 |
useHttpOnly="true" |
是否为会话 Cookie 设置 HttpOnly 属性,有助于减轻跨站脚本(XSS)攻击的风险。生产环境应设为 true 。 |
元素/属性 (Element/Attribute) | 作用与描述 |
---|---|
<Resource> |
定义 JNDI 资源,最常见的是数据库连接池(DataSource)。 |
name="jdbc/MyDB" |
资源的 JNDI 名称。应用将在 java:comp/env/jdbc/MyDB 下查找此资源。 |
auth="Container" |
指定由容器(Tomcat)来管理资源的认证。 |
type="javax.sql.DataSource" |
资源的 Java 类型。对于数据库连接池,这是 javax.sql.DataSource 。 |
username="dbuser" password="dbpass" |
连接数据库的用户名和密码。 |
driverClassName="com.mysql.cj.jdbc.Driver" |
JDBC 驱动类的全限定名。 |
url="jdbc:mysql://localhost:3306/mydb" |
数据库的 JDBC 连接 URL。 |
maxTotal="20" maxIdle="10" minIdle="5" maxWaitMillis="10000" |
连接池关键性能参数。maxTotal :最大活动连接数;maxIdle :最大空闲连接数;minIdle :最小空闲连接数;maxWaitMillis :获取连接的最大等待时间(毫秒)。 |
validationQuery="SELECT 1" |
用于验证连接是否有效的简单 SQL 查询语句。 |
testOnBorrow="true" |
在从池中借出连接前是否进行验证。建议为 true ,确保应用拿到的连接是有效的。 |
<ResourceLink> |
用于在当前应用的 JNDI 上下文中链接(引用) 在全局 (server.xml 或 globalNamingResources ) 中定义的资源。 |
元素/属性 (Element/Attribute) | 作用与描述 |
---|---|
<Manager> |
配置会话管理器,控制如何创建、管理会话。 |
className="org.apache.catalina.session.PersistentManager" |
指定管理器实现类。PersistentManager 会在会话空闲时将其序列化到存储中(如磁盘),适合大型应用或集群环境。 |
className="org.apache.catalina.session.StandardManager" |
默认管理器。重启 Tomcat 时会将会话序列化到磁盘,但运行时所有会话都在内存中。 |
<Store> |
与 PersistentManager 配合使用,定义会话的持久化存储方式(如文件存储 FileStore 或 JDBC 存储 JDBCStore )。 |
<Valve className="org.apache.catalina.valves.PersistentValve" /> |
启用会话持久化功能的阀门。 |
<SessionConfig> |
(Tomcat 8.5+ 推荐方式) 用于配置会话相关参数,替代旧属性。 |
<cookie> |
在 <SessionConfig> 内,用于配置会话 Cookie 的属性。 |
httpOnly="true" |
(在 <cookie> 内)同上,设置 HttpOnly 属性。 |
secure="true" |
(在 <cookie> 内)指示浏览器仅通过 HTTPS 协议发送会话 Cookie。在启用 HTTPS 的生产环境中应设为 true 。 |
元素/属性 (Element/Attribute) | 作用与描述 |
---|---|
<Valve> |
阀门,用于在请求处理管道中插入处理逻辑,功能类似过滤器,但更底层。 |
className="org.apache.catalina.valves.RemoteIpValve" |
极其重要。当 Tomcat 前面有反向代理(如 Nginx, Apache HTTPD)时,此阀门用于识别原始客户端的真实 IP。它会处理 X-Forwarded-For , X-Forwarded-Proto 等头信息。 |
className="org.apache.catalina.valves.AccessLogValve" |
为此特定应用配置访问日志,格式和输出位置可与全局的 Host 级别访问日志不同。 |
className="org.apache.catalina.authenticator.FormAuthenticator" |
处理 FORM 表单认证的阀门。 |
元素/属性 (Element/Attribute) | 作用与描述 |
---|---|
<Environment> |
配置一个作为 JNDI 环境条目(java:comp/env/ )的变量,应用可以通过 InitialContext.lookup() 获取。 |
name="appSettings/configPath" value="/opt/config" type="java.lang.String" |
例如,定义一个字符串类型的环境变量,应用可通过 java:comp/env/appSettings/configPath 获取其值 "/opt/config" 。常用于解耦配置。 |
<Loader> |
定义自定义的类加载器行为。 |
delegate="true" |
类加载委托模式。默认为 false (Tomcat 先自己加载类,不行再委托给父加载器)。设为 true 则遵循标准 Java 双亲委托模型。在某些复杂依赖场景下可能需要调整。 |
3.2.4 conf/tomcat-users.xml
tomcat-users.xml
:用户、角色和认证信息的配置,用于管理能够访问 Tomcat 管理界面(如 Manager 和 Host Manager)或受保护 Web 应用资源的用户、角色和组(但组不常用)。它核心定义了“谁”(用户)拥有“什么权限”(角色)。
tomcat-users.xml示例:
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<!-- 定义Tomcat内置的管理角色 -->
<role rolename="manager-gui"/>
<role rolename="manager-status"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<!-- 1. 监控专用账户:仅能查看服务器状态,无法进行任何管理操作 -->
<user username="status_monitor" password="Very$tr0ngP@ssw0rd1" roles="manager-status"/>
<!-- 2. 自动化部署账户 (供CI/CD工具如Jenkins使用):允许通过脚本接口部署 -->
<user username="ci_deploy_user" password="Another$tr0ngP@ssw0rd!" roles="manager-script"/>
<!-- 3. 管理员账户 (应极少使用且权限分离) -->
<!-- 3.1 Web应用管理员:能通过GUI界面管理Web应用,但不能管理虚拟主机 -->
<user username="app_admin" password="Super$ecureP@ss2" roles="manager-gui"/>
<!-- 3.2 虚拟主机管理员:能管理虚拟主机 -->
<user username="host_admin" password="HostAdmin@123" roles="admin-gui"/>
<!-- 3.3 超级管理员 (仅在紧急情况下使用):拥有所有权限 -->
<user username="super_admin" password="Extremely!Complex@Pass" roles="manager-gui, manager-script, manager-jmx, manager-status, admin-gui, admin-script"/>
</tomcat-users>
配置元素 (Element) | 作用描述 | 属性 (Attributes) | 示例或备注 |
---|---|---|---|
<tomcat-users> |
根元素,包含所有用户、角色和组的定义。 | 无 | <tomcat-users> ... </tomcat-users> |
<role> |
定义一个角色。角色代表一组权限,例如访问特定管理功能的权限。 | rolename : 角色名称。 |
<role rolename="manager-gui"/> 注意:角色名通常是 Tomcat 内置的,自定义角色需与 web.xml 中的安全约束配合使用。 |
<user> |
定义一个用户,并为其分配角色。 | username : 用户名。 password : 密码。 roles : 分配给该用户的角色列表,多个角色用英文逗号分隔。 |
<user username="admin" password="secret" roles="manager-gui, admin-gui"/> 安全提醒:生产环境务必使用强密码。 |
<group> (较少使用) |
定义一个用户组,可以将多个用户归入一个组,便于批量管理角色(但实践中直接为用户分配角色更常见)。 | groupname : 组名称。 |
<group groupname="tomcat-group"/> 需要与用户配置配合使用。 |
角色名称 (rolename) | 授予的访问权限 |
---|---|
manager-gui |
允许访问 Manager App 的 HTML 图形界面(用于部署和管理 Web 应用程序)。 |
manager-script |
允许访问 Manager 的基于文本的接口和状态页面(为诸如 Ant 脚本或 CI/CD 工具等自动化工具提供支持)。 |
manager-jmx |
允许访问 JMX 代理接口和“服务器状态”页面。 |
manager-status |
仅允许访问“服务器状态”(Server Status)页面以查看服务器运行状况。 |
admin-gui |
允许访问 Host Manager 的 HTML 图形界面(用于管理虚拟主机)。 |
admin-script |
允许访问 Host Manager 的脚本接口。 |