源组织
目录
目录结构
以下说明使用变量名称 $CATALINA_BASE 指代大多数相对路径所解析到的基本目录。如果您尚未通过设置 CATALINA_BASE 目录为 Tomcat 配置多个实例,则 $CATALINA_BASE 将设置为 $CATALINA_HOME 的值,即您安装 Tomcat 的目录。
本手册的一个关键建议是将包含源代码的目录层次结构(本节中所述)与包含可部署应用程序的目录层次结构(上一节中所述)分开。保持这种分离具有以下优点
如果应用程序的“可执行”版本没有混杂在一起,则源目录的内容可以更轻松地进行管理、移动和备份。
仅包含源文件的目录上的源代码控制更容易管理。
当部署层次结构是独立时,构成应用程序的可安装分发包的文件更容易选择。
正如我们将看到的,ant
开发工具使得创建和处理此类目录层次结构几乎毫不费力。
用于包含应用程序源代码的实际目录和文件层次结构可以是您喜欢的任何内容。但是,以下组织已被证明具有相当普遍的适用性,并且是下面讨论的示例 build.xml
配置文件所期望的。所有这些组件都存在于应用程序的顶级项目源目录中
- docs/ - 应用程序的文档,采用您的开发团队正在使用的任何格式。
- src/ - 生成对您的应用程序来说唯一的 servlet、bean 和其他 Java 类的 Java 源文件。如果您的源代码按包组织(强烈推荐),则包层次结构应反映在此目录下的目录结构中。
- web/ - 应用程序客户端可以访问的网站的静态内容(HTML 页面、JSP 页面、JavaScript 文件、CSS 样式表文件和图像)。此目录将成为 Web 应用程序的文档根,并且此处找到的任何子目录结构都将反映在访问这些文件所需的请求 URI 中。
- web/WEB-INF/ - 应用程序所需的特殊配置文件,包括 Web 应用程序部署描述符(
web.xml
,在Servlet 规范中定义)、您创建的自定义标记库的标记库描述符以及您希望在 Web 应用程序中包含的其他资源文件。即使此目录看起来是文档根的子目录,但 Servlet 规范禁止将此目录(或其中包含的任何文件)的内容直接提供给客户端请求。因此,这是一个存储敏感配置信息(例如数据库连接用户名和密码)的好地方,但应用程序需要这些信息才能成功运行。
在开发过程中,将临时创建两个其他目录
- build/ - 当您执行默认构建(
ant
)时,此目录将包含此应用程序的 Web 应用程序存档中的文件的精确映像。Tomcat 允许您以这种方式在未打包的目录中部署应用程序,方法是将其复制到$CATALINA_BASE/webapps
目录,或通过“管理器”Web 应用程序安装它。后一种方法在开发过程中非常有用,如下所示。 - dist/ - 当您执行
ant dist
目标时,将创建此目录。它将创建 Web 应用程序的二进制分发的精确映像,包括您准备的许可证信息、文档和 README 文件。
请注意,这两个目录不应存档在您的源代码控制系统中,因为它们在开发过程中会根据需要删除并重新创建(从头开始)。因此,如果您想保留更改的永久记录,则不应编辑这些目录中的任何源文件,因为下次执行构建时这些更改将丢失。
外部依赖项
如果您的应用程序需要来自外部项目或包的 JAR 文件(或其他资源),该怎么办?一个常见的示例是您需要在 Web 应用程序中包含 JDBC 驱动程序才能操作。
不同的开发人员对这个问题有不同的解决方法。一些人会鼓励将您依赖的 JAR 文件的副本检入到每个需要这些 JAR 文件的应用程序的源代码控制存档中。但是,当您在许多应用程序中使用相同的 JAR 时,这可能会导致重大的管理问题——尤其是在需要升级到该 JAR 文件的不同版本时。
因此,本手册建议您不要将您依赖的包存储在应用程序的源代码控制存档中。相反,外部依赖项应作为构建应用程序过程的一部分进行集成。这样,您始终可以从开发系统管理员安装它们的任何位置获取 JAR 文件的适当版本,而无需担心每次更改依赖 JAR 文件的版本时都必须更新您的应用程序。
在示例 Ant build.xml
文件中,我们将演示如何定义构建属性,它允许您配置待复制文件的位置,而无需在这些文件更改时修改 build.xml
。特定开发者使用的构建属性可以在每个应用程序的基础上进行自定义,或默认为存储在开发者主目录中的“标准”构建属性。
在许多情况下,您的开发系统管理员已经将必需的 JAR 文件安装到 Tomcat 的 lib
目录中。如果已完成此操作,则您无需执行任何操作 - 示例 build.xml
文件会自动构建一个包含这些文件的编译类路径。
源代码控制
如前所述,强烈建议您将构成应用程序的所有源文件置于源代码控制系统的管理之下。如果您选择这样做,则应注册和保存源层次结构中的每个目录和文件 -- 但不应保存任何生成的文件。如果您注册二进制格式文件(例如图像或 JAR 库),请务必向您的源代码控制系统指明这一点。
我们(在上一个部分中)建议您不要将开发过程创建的 build/
和 dist/
目录的内容存储在源代码控制系统中。源代码控制系统通常提供忽略这些目录的机制(Git 使用 .gitignore
文件,Subversion 使用 svn:ignore
属性,CVS 使用 .cvsignore
文件,等等)。您应配置源代码控制系统以忽略
- build
- dist
- build.properties
在此处提及 build.properties
的原因将在 流程 部分中进行说明。
有关源代码控制环境的详细说明超出了本手册的范围。
BUILD.XML 配置文件
我们将使用 ant 工具来管理 Java 源代码文件的编译以及部署层次结构的创建。Ant 在构建文件的控制下运行,通常称为 build.xml
,它定义了所需的处理步骤。此文件存储在源代码层次结构的顶级目录中,并且应签入到源代码控制系统中。
与 Makefile 类似,build.xml
文件提供了几个“目标”,这些目标支持可选的开发活动(例如,创建关联的 Javadoc 文档、擦除部署主目录以便您可以从头开始构建项目,或创建 Web 应用程序存档文件以便您可以分发应用程序。一个构建良好的 build.xml
文件将包含内部文档,描述针对开发者使用的目标与内部使用的目标。
ant -projecthelp
为了让您快速上手,我们提供了一个基本的 build.xml 文件,您可以对其进行自定义,并将其安装在应用程序的项目源目录中。此文件包含描述可执行的各种目标的注释。简而言之,通常会提供以下目标
- clean - 此目标会删除任何现有的
build
和dist
目录,以便可以从头开始重建它们。这可让您确保您未对源代码进行修改,从而导致在运行时由于未重新编译所有受影响的类而出现问题。 - compile - 此目标用于编译自上次编译以来已更改的任何源代码。生成的类文件将创建在
build
目录的WEB-INF/classes
子目录中,这正是 Web 应用程序结构要求它们所在的位置。由于在开发过程中经常执行此命令,因此通常将其设为“默认”目标,以便简单的ant
命令即可执行它。 - all - 此目标是运行
clean
目标,然后运行compile
目标的快捷方式。因此,它可确保您将重新编译整个应用程序,以确保您不知不觉地引入了任何不兼容的更改。 - javadoc - 此目标为该 Web 应用程序中的 Java 类创建 Javadoc API 文档。示例
build.xml
文件假定您希望将 API 文档包含在您的应用程序分发中,因此它在dist
目录的子目录中生成文档。由于您通常不需要在每次编译时生成 Javadoc,因此此目标通常是dist
目标的依赖项,但不是compile
目标的依赖项。 - dist - 此目标为您的应用程序创建一个分发目录,其中包括任何必需的文档、Java 类的 Javadoc 以及将提供给希望安装您应用程序的系统管理员的 Web 应用程序存档 (WAR) 文件。由于此目标还依赖于
deploy
目标,因此 Web 应用程序存档还将获取在部署时包含的任何外部依赖项。
对于使用 Tomcat 对您的 Web 应用程序进行交互式开发和测试,定义了以下其他目标
- install - 告知当前运行的 Tomcat 立即让您正在开发的应用程序可用于执行和测试。此操作不需要重新启动 Tomcat,但也不会在下次重新启动 Tomcat 后被记住。
- 重新加载 - 安装应用程序后,可以使用
compile
目标继续进行更改并重新编译。Tomcat 将自动识别对 JSP 页面的更改,但不会识别对 servlet 或 JavaBean 类的更改 - 此命令将指示 Tomcat 重新启动当前安装的应用程序,以便识别此类更改。 - 删除 - 完成开发和测试活动后,可以选择指示 Tomcat 从服务中删除此应用程序。
使用开发和测试目标需要一些其他的一次性设置,将在下一页中进行说明。