4.4 Context 配置文件 (context.xml)


文档摘要

4.4 Context 配置文件 (context.xml) 第四章:Web 应用部署 - 4.4 Context 配置文件 (context.xml) 详解 在 Tomcat 服务器中,Web 应用的部署是至关重要的环节。Tomcat 提供了多种方式来配置和部署 Web 应用,而 配置文件则是其中一个核心且灵活的方式。它允许开发者精细地控制 Web 应用的运行环境、资源、安全以及会话管理等各个方面。本章节将深入探讨 配置文件,帮助您理解其结构、配置选项以及如何在实践中有效使用。 4.4.1 的作用与位置 文件在 Tomcat 中扮演着定义 Web 应用上下文(Context)的角色。

4.4 Context 配置文件 (context.xml)

第四章:Web 应用部署 - 4.4 Context 配置文件 (context.xml) 详解

在 Tomcat 服务器中,Web 应用的部署是至关重要的环节。Tomcat 提供了多种方式来配置和部署 Web 应用,而 context.xml 配置文件则是其中一个核心且灵活的方式。它允许开发者精细地控制 Web 应用的运行环境、资源、安全以及会话管理等各个方面。本章节将深入探讨 context.xml 配置文件,帮助您理解其结构、配置选项以及如何在实践中有效使用。

4.4.1 context.xml 的作用与位置

context.xml 文件在 Tomcat 中扮演着定义 Web 应用上下文(Context)的角色。Context 在 Tomcat 中代表一个独立的 Web 应用,它拥有自己的类加载器、Servlet 容器、会话管理器以及安全域等。context.xml 允许您为特定的 Web 应用定制这些组件的行为和属性,而无需修改 Tomcat 服务器的全局配置文件。

context.xml 的主要作用包括:

  • 定义 Web 应用的上下文路径 (Context Path): Context Path 是访问 Web 应用的 URL 前缀。context.xml 可以显式地设置 Context Path,或者依赖于部署目录或 WAR 文件名自动生成。

  • 配置 Web 应用的文档根目录 (Document Base): Document Base 指向 Web 应用的静态资源(如 HTML、CSS、JavaScript、图片等)和 Web 应用描述符 (web.xml) 所在的目录。

  • 配置资源 (Resources): context.xml 可以定义 Web 应用可访问的各种资源,如数据源 (DataSource)、邮件会话 (Mail Session)、JNDI 资源等。

  • 配置会话管理器 (Session Manager): 可以自定义会话管理器的实现,例如使用持久化会话管理器,以便在服务器重启后会话仍然有效。

  • 配置安全域 (Realm): 定义 Web 应用的安全认证和授权机制,例如使用 JDBCRealm、MemoryRealm 等。

  • 配置阀门 (Valves): Valve 是 Tomcat 中请求处理管道的组件,context.xml 可以配置 Valve 来实现请求日志记录、安全检查、URL 重写等功能。

  • 配置生命周期监听器 (Listeners): 监听 Web 应用的启动、停止等生命周期事件,并执行自定义的操作。

  • 配置类加载器 (Loader): 自定义 Web 应用的类加载行为,例如指定额外的类路径。

  • 其他配置: 包括配置环境变量、初始化参数、Cookie 处理器、JSP 配置等。

context.xml 的位置:

context.xml 文件可以放置在两个主要位置,影响其作用范围:

  1. Tomcat 全局 Context 配置文件 ($CATALINA_BASE/conf/context.xml)

    • 位于 Tomcat 安装目录的 conf 目录下,名为 context.xml 的文件。

    • 该文件定义的配置将作为默认配置应用于所有部署到 Tomcat 中的 Web 应用。

    • 通常用于设置通用的、应用于所有 Web 应用的默认属性,例如默认的会话管理器、默认的阀门等。

    • 不建议在该文件中定义特定于某个 Web 应用的配置,因为它会影响所有应用。

  2. Web 应用特定的 Context 配置文件 ($CATALINA_BASE/conf/[enginename]/[hostname]/[webappname].xml 或 Web 应用的 META-INF/context.xml)

    • 服务器 Context 文件: 位于 $CATALINA_BASE/conf/[enginename]/[hostname]/ 目录下,文件名为 [webappname].xml,其中 [webappname] 是 Web 应用的 Context Path 或部署目录名。

      • 例如,对于 Context Path 为 /myapp 的 Web 应用,配置文件可能位于 $CATALINA_BASE/conf/Catalina/localhost/myapp.xml

      • 这种方式允许为特定的 Web 应用配置 Context,且配置优先级高于全局 context.xml

    • Web 应用内部 Context 文件: 位于 Web 应用的 META-INF 目录下,名为 context.xml 的文件。

      • 该文件与 Web 应用打包在一起,例如在 WAR 文件中,位于 META-INF/context.xml

      • 这种方式将 Context 配置与 Web 应用紧密结合,方便部署和移植。

      • 如果同时存在服务器 Context 文件和 Web 应用内部 Context 文件,服务器 Context 文件中的配置将覆盖 Web 应用内部 Context 文件中的配置

优先级顺序 (从低到高):

  1. Tomcat 默认配置 (硬编码在 Tomcat 代码中)

  2. 全局 Context 配置文件 ($CATALINA_BASE/conf/context.xml)

  3. Web 应用内部 Context 配置文件 (META-INF/context.xml)

  4. 服务器 Context 配置文件 ($CATALINA_BASE/conf/[enginename]/[hostname]/[webappname].xml)

  5. 部署描述符 (web.xml) 以及注解等 Web 应用自身的配置

Mermaid 图示:context.xml 位置与优先级

说明:优先级从上到下依次升高,最终 Web 应用配置是所有配置合并和覆盖的结果。

4.4.2 context.xml 的基本结构

context.xml 文件是一个标准的 XML 文件,其根元素是 <Context>。一个典型的 context.xml 文件结构如下所示:

<?xml version="1.0" encoding="UTF-8"?> <Context path="/myapp" docBase="myapp" reloadable="true"> <!-- 配置资源 (例如数据源) --> <Resource name="jdbc/MyDataSource" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb" username="user" password="password" maxActive="20" maxIdle="10"/> <!-- 配置会话管理器 --> <Manager className="org.apache.catalina.session.PersistentManager"> <Store className="org.apache.catalina.session.FileStore" directory="sessions"/> </Manager> <!-- 配置阀门 (例如访问日志) --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="myapp_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b"/> <!-- 配置环境参数 --> <Environment name="MY_ENV_VAR" value="my_env_value" type="java.lang.String"/> <!-- 配置初始化参数 --> <Parameter name="myWebAppParam" value="myWebAppValue"/> <!-- 配置生命周期监听器 --> <Listener className="com.example.MyContextListener"/> </Context>

<Context> 元素的主要属性:

  • path (Context Path): 指定 Web 应用的 Context Path。

    • 如果部署的是 WAR 文件,并且 path 属性与 WAR 文件名(不含 .war 扩展名)相同,则可以省略 path 属性。

    • 如果部署的是展开目录,并且 path 属性与目录名相同,也可以省略 path 属性。

    • 如果设置 path=""path="/",则该 Web 应用将成为默认 Web 应用(根 Context)。

  • docBase (Document Base): 指定 Web 应用的文档根目录的路径。

    • 可以是绝对路径,也可以是相对于 $CATALINA_BASE 的相对路径。

    • 如果部署的是 WAR 文件,docBase 通常指向 WAR 文件名(包含 .war 扩展名)。Tomcat 会自动解压 WAR 文件到 $CATALINA_BASE/webapps 目录下,并将 docBase 指向解压后的目录。

    • 如果部署的是展开目录,docBase 通常指向该展开目录。

  • reloadable (是否可重载): 布尔值,默认为 false

    • 如果设置为 true,Tomcat 会在后台监控 WEB-INF/classesWEB-INF/lib 目录下的文件变化。当文件发生变化时,Tomcat 会自动重新加载 Web 应用,无需重启 Tomcat 服务器。

    • 在开发阶段非常方便,但在生产环境中建议设置为 false,以避免性能损耗和潜在的线程安全问题。

  • crossContext (是否允许跨 Context 访问): 布尔值,默认为 false

    • 如果设置为 true,允许该 Web 应用的 ServletContext 访问同一 Tomcat 实例中其他 Web 应用的 ServletContext 属性。

    • 通常情况下,Web 应用之间是相互隔离的,不建议启用跨 Context 访问,除非有明确的需求。

  • privileged (是否为特权 Context): 布尔值,默认为 false

    • 如果设置为 true,该 Web 应用将被视为特权 Context,可以执行一些受限的操作,例如设置 ServletContext 属性、访问 Tomcat 的管理 API 等。

    • 通常情况下,只有 Tomcat 管理 Web 应用(例如 Host Manager、Manager 应用)才需要设置为特权 Context。

  • antiJARLocking (防止 JAR 文件锁定): 布尔值,默认为 false (在 Windows 系统上默认为 true)。

    • 如果设置为 true,Tomcat 会将 WEB-INF/lib 目录下的 JAR 文件复制到一个临时目录,并从临时目录加载 JAR 文件。这可以防止在 Windows 系统上 Web 应用停止后 JAR 文件仍然被锁定,导致无法更新或删除 Web 应用。

    • 在 Linux/Unix 系统上通常不需要设置 antiJARLocking

  • swallowOutput (吞噬 System.out 和 System.err 输出): 布尔值,默认为 false

    • 如果设置为 true,Tomcat 会捕获 Web 应用中 System.out.println()System.err.println() 的输出,并将其重定向到 Tomcat 的日志文件中。

    • 在生产环境中建议设置为 true,以便更好地管理 Web 应用的日志输出。

  • mapperContextRootRedirectEnabled (Context Root 重定向): 布尔值,默认为 true

    • 当用户访问 Context Path 为根路径 ("/") 的 Web 应用时,如果 URL 没有以 "/" 结尾,Tomcat 会自动重定向到以 "/" 结尾的 URL。

    • 例如,如果用户访问 http://localhost:8080,Tomcat 会重定向到 http://localhost:8080/

  • mapperDirectoryRedirectEnabled (目录重定向): 布尔值,默认为 true

    • 当用户访问一个目录时,如果 URL 没有以 "/" 结尾,Tomcat 会自动重定向到以 "/" 结尾的 URL。

    • 例如,如果用户访问 http://localhost:8080/myapp/mydir,Tomcat 会重定向到 http://localhost:8080/myapp/mydir/

4.4.3 context.xml 的主要子元素详解与代码实践

<Context> 元素可以包含多个子元素,用于配置 Web 应用的各个方面。以下将详细介绍一些常用的子元素,并提供代码实践示例。

4.4.3.1 <Resource><ResourceLink>:配置 JNDI 资源

<Resource> 元素用于在 JNDI (Java Naming and Directory Interface) 上注册一个资源,例如数据源 (DataSource)、邮件会话 (Mail Session) 等。Web 应用可以通过 JNDI 查找和使用这些资源。

<Resource> 元素的主要属性:

  • name (资源 JNDI 名称): 指定资源的 JNDI 名称,Web 应用通过该名称查找资源。通常以 java:comp/env/ 为前缀,例如 java:comp/env/jdbc/MyDataSource

  • auth (认证类型): 指定资源的认证类型,通常设置为 Container,表示由 Tomcat 容器进行认证。

  • type (资源类型): 指定资源的 Java 类型,例如 javax.sql.DataSourcejavax.mail.Session 等。

  • 其他属性: 不同的资源类型有不同的属性,例如 javax.sql.DataSource 需要配置 driverClassNameurlusernamepassword 等数据库连接信息。

代码实践:配置 MySQL 数据源

假设我们需要配置一个名为 jdbc/MyDataSource 的 MySQL 数据源。在 context.xml 中添加以下 <Resource> 元素:

<Context path="/myapp" docBase="myapp" reloadable="true"> <Resource name="jdbc/MyDataSource" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai" username="user" password="password" maxActive="20" maxIdle="10" validationQuery="SELECT 1"/> </Context>

代码实践:在 Servlet 中使用数据源

在 Servlet 中,可以通过 JNDI 查找并使用配置的数据源:

import javax.annotation.Resource; 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.sql.DataSource; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; @WebServlet("/dataSourceTest") public class DataSourceTestServlet extends HttpServlet { @Resource(name = "jdbc/MyDataSource") private DataSource dataSource; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (Connection connection = dataSource.getConnection()) { resp.getWriter().println("Successfully connected to database!"); } catch (SQLException e) { resp.getWriter().println("Failed to connect to database: " + e.getMessage()); e.printStackTrace(); } } }

<ResourceLink> 元素:链接全局资源

<ResourceLink> 元素用于链接在 Tomcat 服务器全局配置 ($CATALINA_BASE/conf/server.xml 或全局 context.xml) 中定义的资源。当需要在多个 Web 应用之间共享同一个资源时,可以使用 <ResourceLink>

<ResourceLink> 元素的主要属性:

  • name (链接的 JNDI 名称): 指定链接在当前 Context 中的 JNDI 名称。

  • global (全局资源 JNDI 名称): 指定全局资源在全局配置中定义的 JNDI 名称。

  • type (资源类型): 指定资源的 Java 类型,必须与全局资源的类型一致。

代码实践:链接全局数据源

假设在全局 context.xml 中定义了一个名为 global/MyGlobalDataSource 的数据源,现在需要在 Web 应用 myapp 中使用该数据源,并将其链接为 jdbc/MyLinkedDataSource。在 myappcontext.xml 中添加以下 <ResourceLink> 元素:

<Context path="/myapp" docBase="myapp" reloadable="true"> <ResourceLink name="jdbc/MyLinkedDataSource" global="global/MyGlobalDataSource" type="javax.sql.DataSource"/> </Context>

Web 应用可以使用 JNDI 名称 java:comp/env/jdbc/MyLinkedDataSource 访问全局数据源 global/MyGlobalDataSource

Mermaid 图示:<Resource><ResourceLink>

说明:<Resource> 直接定义资源,<ResourceLink> 链接到全局定义的资源。

4.4.3.2 <Manager>:配置会话管理器

<Manager> 元素用于配置 Web 应用的会话管理器,负责创建、管理和持久化会话。

<Manager> 元素的主要属性:

  • className (管理器类名): 指定会话管理器的实现类,默认为 org.apache.catalina.session.StandardManager (内存会话管理器)。

    • 常用的会话管理器类包括:

      • org.apache.catalina.session.StandardManager (默认,内存会话管理器,服务器重启后会话丢失)

      • org.apache.catalina.session.PersistentManager (持久化会话管理器,可以将会话持久化到文件系统或数据库)

      • org.apache.catalina.session.JDBCStore (JDBC 会话存储,用于 PersistentManager,将会话存储到数据库)

      • org.apache.catalina.session.FileStore (文件会话存储,用于 PersistentManager,将会话存储到文件系统)

  • 其他属性: 不同的会话管理器类有不同的属性,例如 PersistentManager 需要配置 <Store> 子元素来指定会话存储方式。

代码实践:配置持久化会话管理器 (FileStore)

以下配置使用 PersistentManagerFileStore,将 Web 应用的会话持久化到文件系统,存储在 $CATALINA_BASE/sessions 目录下。

<Context path="/myapp" docBase="myapp" reloadable="true"> <Manager className="org.apache.catalina.session.PersistentManager"> <Store className="org.apache.catalina.session.FileStore" directory="sessions"/> </Manager> </Context>

代码实践:配置持久化会话管理器 (JDBCStore)

以下配置使用 PersistentManagerJDBCStore,将 Web 应用的会话持久化到数据库。需要先配置一个数据源 jdbc/SessionDB 用于会话存储。

<Context path="/myapp" docBase="myapp" reloadable="true"> <Resource name="jdbc/SessionDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/sessiondb?serverTimezone=Asia/Shanghai" username="session_user" password="session_password" maxActive="10" maxIdle="5"/> <Manager className="org.apache.catalina.session.PersistentManager"> <Store className="org.apache.catalina.session.JDBCStore" dataSourceName="jdbc/SessionDB" sessionTable="app_sessions" sessionAppCol="app_name" sessionDataCol="session_data" sessionValidCol="session_valid" sessionLastAccessedCol="last_access"/> </Manager> </Context>

Mermaid 图示:<Manager><Store>

说明:<Manager> 配置会话管理器,<Store> 配置会话存储方式,PersistentManager 需要配合 <Store> 使用。

4.4.3.3 <Valve>:配置阀门 (请求处理管道)

<Valve> 元素用于配置 Tomcat 请求处理管道中的阀门。Valve 可以拦截和处理请求,实现诸如请求日志记录、安全检查、URL 重写等功能。

<Valve> 元素的主要属性:

  • className (阀门类名): 指定阀门的实现类。

    • 常用的阀门类包括:

      • org.apache.catalina.valves.AccessLogValve (访问日志阀门,记录请求访问日志)

      • org.apache.catalina.valves.RemoteAddrValve (远程地址阀门,基于远程 IP 地址进行访问控制)

      • org.apache.catalina.valves.RemoteHostValve (远程主机名阀门,基于远程主机名进行访问控制)

      • org.apache.catalina.valves.rewrite.RewriteValve (URL 重写阀门,使用 Apache httpd mod_rewrite 规则进行 URL 重写)

  • 其他属性: 不同的阀门类有不同的属性,例如 AccessLogValve 需要配置日志文件目录、文件名、日志格式等。

代码实践:配置访问日志阀门

以下配置使用 AccessLogValve,将 Web 应用的访问日志记录到 $CATALINA_BASE/logs 目录下的 myapp_access_log.txt 文件中,日志格式为通用日志格式 (CLF)。

<Context path="/myapp" docBase="myapp" reloadable="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="myapp_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b"/> </Context>

代码实践:配置 RemoteAddrValve (IP 地址访问控制)

以下配置使用 RemoteAddrValve,只允许来自 192.168.1.0/24 网段的 IP 地址访问 Web 应用。

<Context path="/myapp" docBase="myapp" reloadable="true"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192\.168\.1\.\d+"/> </Context>

Mermaid 图示:<Valve> 和 请求处理管道

说明:<Valve> 配置的阀门在请求处理管道中按顺序执行,可以对请求进行拦截和处理。

4.4.3.4 <Listener>:配置生命周期监听器

<Listener> 元素用于配置 Web 应用的生命周期监听器。监听器可以监听 Web 应用的启动、停止、会话创建、会话销毁等事件,并在事件发生时执行自定义的操作。

<Listener> 元素的主要属性:

  • className (监听器类名): 指定监听器的实现类,必须实现 javax.servlet.ServletContextListenerjavax.servlet.http.HttpSessionListener 或其他相关的监听器接口。

代码实践:配置 ServletContextListener

假设我们有一个自定义的 MyContextListener 类,实现了 ServletContextListener 接口,用于在 Web 应用启动和停止时打印日志。

package com.example; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("Web application started: " + sce.getServletContext().getContextPath()); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("Web application stopped: " + sce.getServletContext().getContextPath()); } }

context.xml 中配置 MyContextListener

<Context path="/myapp" docBase="myapp" reloadable="true"> <Listener className="com.example.MyContextListener"/> </Context>

当 Web 应用启动时,contextInitialized() 方法会被调用,控制台会输出 "Web application started: /myapp"。当 Web 应用停止时,contextDestroyed() 方法会被调用,控制台会输出 "Web application stopped: /myapp"。

Mermaid 图示:<Listener> 和 Web 应用生命周期

说明:<Listener> 监听 Web 应用生命周期事件,并在事件发生时执行自定义操作。

4.4.3.5 其他常用子元素

  • <Parameter>:配置初始化参数

    用于配置 Web 应用的初始化参数,可以通过 ServletContext.getInitParameter() 方法获取。

    <Context path="/myapp" docBase="myapp" reloadable="true"> <Parameter name="appName" value="MyWebApp"/> </Context>

    在 Servlet 中获取参数:

    String appName = getServletContext().getInitParameter("appName");
  • <Environment>:配置环境变量

    用于配置 Web 应用的环境变量,可以通过 JNDI 访问,JNDI 名称以 java:comp/env/env/ 为前缀。

    <Context path="/myapp" docBase="myapp" reloadable="true"> <Environment name="MY_ENV_VAR" value="my_env_value" type="java.lang.String"/> </Context>

    在代码中通过 JNDI 获取环境变量:

    import javax.naming.InitialContext; import javax.naming.NamingException; String envVarValue = (String) new InitialContext().lookup("java:comp/env/env/MY_ENV_VAR");
  • <Realm>:配置安全域

    用于配置 Web 应用的安全认证和授权机制,例如使用 JDBCRealmMemoryRealm 等。Realm 的配置较为复杂,通常需要结合 web.xml 中的安全约束一起使用,这里不再详细展开,可以参考 Tomcat 官方文档关于 Realm 的章节。

  • <JarScanner><JarScanFilter>:控制 JAR 扫描

    用于控制 Tomcat 在启动时扫描 JAR 文件以查找 Servlet 注解、TLD 文件等。可以配置 <JarScanner><JarScanFilter> 来优化 JAR 扫描性能,例如排除某些 JAR 文件或目录。

  • <CookieProcessor><SessionCookieConfig>:配置 Cookie 处理

    用于配置 Cookie 的处理方式,例如 Cookie 的名称、域、路径、安全属性等。可以自定义 Cookie 处理器或配置会话 Cookie 的属性。


发布者: 作者: 转发
评论区 (0)
U