【Web应用服务器_Tomcat】一、Tomcat基础与核心功能详解

在 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
相关推荐
HanhahnaH11 分钟前
Spring集合注入Bean
java·spring
未定义.22117 分钟前
电子削铅笔刀顺序图详解:从UML设计到PlantUML实现
java·软件工程·uml
小墨宝25 分钟前
js 生成pdf 并上传文件
前端·javascript·pdf
雾月5534 分钟前
LeetCode 1292 元素和小于等于阈值的正方形的最大边长
java·数据结构·算法·leetcode·职场和发展
HED40 分钟前
用扣子快速手撸人生中第一个AI智能应用!
前端·人工智能
DN金猿44 分钟前
使用npm install或cnpm install报错解决
前端·npm·node.js
丘山子1 小时前
一些鲜为人知的 IP 地址怪异写法
前端·后端·tcp/ip
志存高远661 小时前
Kotlin 的 suspend 关键字
前端
www_pp_1 小时前
# 构建词汇表:自然语言处理中的关键步骤
前端·javascript·自然语言处理·easyui
24k小善2 小时前
Flink TaskManager详解
java·大数据·flink·云计算