在 Java Web 应用开发领域,Apache Tomcat 是一座不可或缺的基石。作为一款开源、轻量级的 Servlet 容器和 Web 服务器,Tomcat 以其稳定可靠、易于部署和高度可定制性,被广泛应用于各类 Web 应用的部署与运行。
一、Tomcat 简介
Tomcat 是 Apache 软件基金会下 Jakarta 项目开发的 Servlet 容器,它实现了 Java EE(Java Platform, Enterprise Edition)或 Jakarta EE(Java EE 的后续演进版本)中的 Servlet、JSP(JavaServer Pages)等核心规范,能够高效地处理 HTTP 请求,运行 Java Web 应用。自 1998 年发布第一个版本以来,Tomcat 不断发展和完善,如今已成为 Java Web 开发者最常用的服务器之一。
Tomcat 与 Java EE、Jakarta EE 平台紧密相连。不同版本的 Tomcat 对应着不同的 Java EE 或 Jakarta EE 规范,例如 Tomcat 9 及更早版本实现 Java EE 规范,而 Tomcat 10 及后续版本实现 Jakarta EE 规范。这种对应关系确保了 Tomcat 能够为基于相应规范开发的 Web 应用提供可靠的运行环境。
在实际应用场景中,从中小型企业的内部管理系统,到大型互联网公司的高并发电商平台,Tomcat 都扮演着关键角色。它的轻量级特性使其能够在资源有限的环境中高效运行,而强大的功能又足以支撑复杂的 Web 应用需求。
二、Tomcat 的安装与启动
2.1 安装环境准备
在 CentOS 7 系统上安装 Tomcat,首先需要确保系统已安装 Java 运行环境(JRE)或 Java 开发工具包(JDK)。可以通过以下命令检查 Java 版本:
bash
java -version
如果系统未安装 Java,可使用以下命令安装 OpenJDK:
bash
sudo yum install java-1.8.0-openjdk-devel
2.2 下载 Tomcat
访问 Tomcat 官方网站(Apache Tomcat® - Welcome!),下载适合的 Tomcat 版本。在 CentOS 7 上,通常选择 Tomcat 的 tar.gz 压缩包。使用wget命令下载 Tomcat 9.0 版本(以实际最新版本为准):
bash
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.71/bin/apache-tomcat-9.0.71.tar.gz
2.3 解压与配置
下载完成后,使用以下命令解压压缩包:
bash
tar -zxvf apache-tomcat-9.0.71.tar.gz
将解压后的 Tomcat 目录移动到合适的位置,例如/usr/local/:
bash
sudo mv apache-tomcat-9.0.71 /usr/local/tomcat
为了方便管理,可创建一个指向 Tomcat 目录的软链接:
bash
sudo ln -s /usr/local/tomcat /usr/local/tomcat-latest
2.4 启动 Tomcat
进入 Tomcat 的bin目录:
bash
cd /usr/local/tomcat-latest/bin
执行启动脚本:
bash
./startup.sh
执行命令后,终端会输出一系列启动信息,表明 Tomcat 正在启动。可以通过查看 Tomcat 的日志文件/usr/local/tomcat-latest/logs/catalina.out来确认启动是否成功。如果启动过程中出现错误,日志文件会记录详细的错误信息,方便排查问题。
三、Tomcat 架构解析
Tomcat 的架构主要由 Server、Service、Connector 和 Container 四大组件构成,它们相互协作,共同完成 Web 请求的处理和响应。
3.1 Server 组件
Server 是 Tomcat 服务器的顶级组件,它代表整个 Tomcat 实例,负责管理一个或多个 Service。在/usr/local/tomcat-latest/conf/server.xml配置文件中,<Server>元素是根元素,定义了 Tomcat 服务器的基本属性和生命周期管理。
XML
<Server port="8005" shutdown="SHUTDOWN">
<!-- 其他配置 -->
</Server>
其中,port属性指定了 Tomcat 服务器用于接收关闭命令的端口号,shutdown属性指定了关闭服务器时发送的命令字符串。当通过该端口发送指定的关闭命令时,Tomcat 服务器会优雅地停止运行。
3.2 Service 组件
Service 组件包含一个或多个 Connector 和一个 Container。它的主要作用是将 Connector 接收到的请求转发给 Container 进行处理,并将 Container 处理后的响应通过 Connector 返回给客户端。在server.xml中,<Service>元素定义了 Service 组件的配置:
XML
<Service name="Catalina">
<!-- Connector配置 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- Container配置 -->
<Engine name="Catalina" defaultHost="localhost">
<!-- 其他配置 -->
</Engine>
</Service>
3.3 Connector 组件
Connector 负责处理网络通信,接收客户端的请求,并将请求转发给 Container。它支持多种协议,如 HTTP/1.1、AJP(Apache JServ Protocol)等。以 HTTP 协议的 Connector 为例,在server.xml中的配置如下:
XML
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
- port:指定 Connector 监听的端口号,默认值为 8080。
- protocol:指定使用的协议,这里是 HTTP/1.1。
- connectionTimeout:指定连接超时时间(单位:毫秒),超过该时间未完成的连接将被关闭。
- redirectPort:当需要将 HTTP 请求重定向到 HTTPS 时,指定重定向的端口号,默认为 8443。
3.4 Container 组件
Container 是 Tomcat 处理请求的核心组件,负责管理和执行 Servlet。它采用分层架构,由 Engine、Host、Context 和 Wrapper 四个子容器组成,层级关系为 Engine → Host → Context → Wrapper。
Engine:代表整个 Servlet 引擎,一个 Service 中只能有一个 Engine。它负责处理来自 Connector 的请求,并将请求分配给合适的 Host。
XML
<Engine name="Catalina" defaultHost="localhost">
<!-- 其他配置 -->
</Engine>
Host:代表一个虚拟主机,用于部署多个 Web 应用。每个 Host 可以包含多个 Context。
XML
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- 其他配置 -->
</Host>
appBase属性指定了 Web 应用的部署目录,默认为webapps目录;unpackWARs属性表示是否自动解压 WAR 文件;autoDeploy属性表示是否自动部署 Web 应用。
Context:代表一个 Web 应用,每个 Web 应用对应一个 Context。它负责管理 Web 应用的资源、Servlet 映射等。
XML
<Context path="/myapp" docBase="/usr/local/tomcat-latest/webapps/myapp"
reloadable="true">
<!-- 其他配置 -->
</Context>
path属性指定了 Web 应用的访问路径;docBase属性指定了 Web 应用的实际目录;reloadable属性表示当 Web 应用的类文件或配置文件发生变化时,是否自动重新加载应用。
Wrapper:代表一个 Servlet,它是 Container 的最底层容器,负责实例化和调用 Servlet。
四、Tomcat 核心功能详解
4.1 Servlet 容器功能
Servlet 是 Java Web 应用的核心组件,用于处理客户端请求并生成响应。Tomcat 作为 Servlet 容器,负责 Servlet 的生命周期管理,包括加载、实例化、初始化、服务请求和销毁。
当 Tomcat 启动时,它会扫描 Web 应用的WEB-INF/classes目录和WEB-INF/lib目录下的类文件,加载所有定义的 Servlet 类。在接收到针对某个 Servlet 的请求时,Tomcat 会实例化该 Servlet 对象(每个 Servlet 在应用中只有一个实例),并调用其init方法进行初始化。然后,通过调用service方法处理请求,根据请求的 HTTP 方法(如 GET、POST 等)调用相应的doGet、doPost等方法。最后,当 Tomcat 关闭或 Web 应用重新部署时,会调用 Servlet 的destroy方法进行资源清理。
以下是一个简单的 Servlet 示例,用于处理用户的登录请求:
java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 模拟登录验证
if ("admin".equals(username) && "123456".equals(password)) {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Login Success</title></head>");
out.println("<body>");
out.println("<h1>Welcome, " + username + "</h1>");
out.println("</body>");
out.println("</html>");
} else {
response.sendRedirect("login.html");
}
}
}
将上述 Servlet 代码编译后,放置在 Web 应用的WEB-INF/classes目录下,Tomcat 会自动识别并处理针对/login路径的请求。
4.2 JSP 支持
JSP 是一种动态网页技术,它允许在 HTML 页面中嵌入 Java 代码,从而实现动态内容的生成。Tomcat 对 JSP 提供了良好的支持,JSP 页面在运行时会被 Tomcat 转换成 Servlet 类并执行。
例如,创建一个简单的 JSP 页面index.jsp,用于显示当前时间:
html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Current Time</title>
</head>
<body>
<h1>Current Time: <%= new java.util.Date() %></h1>
</body>
</html>
当用户访问该 JSP 页面时,Tomcat 会将index.jsp转换成一个 Servlet 类,该 Servlet 类的_jspService方法包含了生成页面内容的逻辑。在首次访问 JSP 页面时,Tomcat 会进行转换和编译操作,后续访问则直接执行已编译的 Servlet 类,提高了响应速度。
4.3 Web 服务器功能
Tomcat 不仅是 Servlet 容器,还具备 Web 服务器的功能,能够处理 HTTP 请求和响应,提供静态资源(如 HTML、CSS、JavaScript 文件等)的服务。
当 Tomcat 接收到一个 HTTP 请求时,首先由 Connector 组件接收请求,然后根据请求的 URL 路径判断是请求静态资源还是动态资源。如果是请求静态资源,Tomcat 会直接从 Web 应用的资源目录中读取相应文件,并将其作为响应返回给客户端;如果是请求动态资源(如 Servlet 或 JSP),则将请求转发给 Container 组件进行处理。
例如,将一个index.html文件放置在 Web 应用的根目录下,用户通过浏览器访问http://localhost:8080/myapp/index.html时,Tomcat 会直接读取该文件并返回给用户。
4.4 管理和部署 Web 应用
4.4.1 部署方式
Tomcat 支持多种 Web 应用的部署方式,常见的有以下两种:
- WAR 文件部署:将 Web 应用打包成 WAR 文件(类似于 ZIP 文件格式),然后将 WAR 文件放置在 Tomcat 的webapps目录下。Tomcat 会自动解压 WAR 文件,并部署其中的 Web 应用。例如,将开发好的myapp.war文件复制到/usr/local/tomcat-latest/webapps目录下,Tomcat 会自动解压并启动该应用。
- 目录结构部署:将 Web 应用的目录结构直接放置在webapps目录下。目录结构应包含WEB-INF目录,其中WEB-INF/classes目录存放 Java 类文件,WEB-INF/lib目录存放依赖的 jar 包,WEB-INF/web.xml文件是 Web 应用的配置文件(在 Servlet 3.0 及以上版本中,也可以通过注解进行配置,web.xml文件不是必需的)。
4.4.2 管理界面
Tomcat 提供了一个基于 Web 的管理界面,方便用户管理和监控 Web 应用。要启用管理界面,需要在/usr/local/tomcat-latest/conf/tomcat-users.xml文件中添加管理用户和角色:
XML
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user username="admin" password="admin" roles="manager-gui,admin-gui"/>
</tomcat-users>
上述配置添加了一个名为admin的用户,具有manager-gui和admin-gui角色,分别用于访问 Web 应用管理界面和服务器管理界面。
添加用户后,重启 Tomcat,通过浏览器访问http://localhost:8080/manager/html(管理 Web 应用)或http://localhost:8080/host-manager/html(管理虚拟主机),输入用户名和密码即可进入管理界面。在管理界面中,可以查看已部署的 Web 应用列表、启动 / 停止应用、部署新应用等操作。
4.5 安全性和会话管理
4.5.1 安全性
Tomcat 提供了多种安全管理功能,包括用户认证、授权和 SSL 支持等。
- 用户认证和授权:通过在tomcat-users.xml文件中配置用户和角色,结合 Web 应用的web.xml文件中的安全约束配置,实现用户认证和授权。例如,在web.xml中配置对某个资源的访问权限:
XML
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Area</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>BASIC</auth-method>
<realm-name>Tomcat Realm</realm-name>
</login-config>
上述配置表示只有具有admin角色的用户才能访问/admin路径下的资源,认证方式为基本认证(BASIC)。
- SSL 支持:为了保障数据传输的安全性,Tomcat 可以配置 SSL 证书,实现 HTTPS 协议。首先需要获取 SSL 证书(可以从证书颁发机构购买或使用自签名证书),然后在server.xml中配置 SSL Connector:
XML
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateFile="conf/localhost.crt"
certificateKeyFile="conf/localhost.key"
type="RSA" />
</SSLHostConfig>
</Connector>
certificateFile属性指定证书文件路径,certificateKeyFile属性指定私钥文件路径。配置完成后,重启 Tomcat,用户即可通过 HTTPS 协议访问 Web 应用。
4.5.2 会话管理
会话管理用于跟踪用户在多次请求之间的状态,例如购物车信息、用户登录状态等。Tomcat 通过HttpSession对象实现会话管理。
当用户首次访问 Web 应用时,Tomcat 会为用户创建一个唯一的会话 ID,并将其通过 Cookie 发送给客户端。后续用户的请求中会携带该会话 ID,Tomcat 根据会话 ID 识别用户的会话,并在服务器端维护会话相关的数据。
以下是一个在 Servlet 中使用会话管理的示例,用于记录用户的访问次数:
java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/counter")
public class CounterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(true);
Integer count