Servlet 包

war 的结构、MANIFEST、打包命令与部署方式。

Intermediate
Key Pointswar 就是一个按 Web 应用目录结构组织的 zip;放进容器的 webapps 目录即自动部署。

war 的结构

Text
myapp.war
├── index.jsp
├── css/
├── js/
├── images/
├── META-INF/
│   └── MANIFEST.MF
└── WEB-INF/
    ├── web.xml
    ├── classes/
    │   └── com/example/HelloServlet.class
    └── lib/
        └── mysql-connector-j.jar

A war is a zip. The container unpacks it, puts WEB-INF/classes and the jars in WEB-INF/lib on the classloader, and serves everything outside WEB-INF directly.

用 Maven 打包

XML
<packaging>war</packaging>

<build>
  <finalName>myapp</finalName>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>3.4.0</version>
    </plugin>
  </plugins>
</build>
Bash
mvn clean package
Output
[INFO] Building war: target/myapp.war
[INFO] BUILD SUCCESS

用 jar 命令打包

Bash
# 在 webapp 目录下执行
jar -cvf myapp.war .

jar only compresses — it neither compiles nor copies dependencies. You must place classes and jars into WEB-INF/classes and WEB-INF/lib yourself, which is why real projects use Maven or Gradle.

部署方式

MethodHowWhen
Copy to webapps把 war 放进 webapps/,容器自动解压部署简单、单机
Context descriptor在 conf/Catalina/localhost/ 放 myapp.xml 指向 warwar 放外部目录
Manager app浏览器登录 Manager 上传 war远程部署
EmbeddedSpring Boot 打成可执行 jar,java -jar现代主流
The context path defaults to the file name: myapp.war serves at /myapp. For the root path, name it ROOT.war or set path="" in the context descriptor.

MANIFEST 里值得写的

Text
Manifest-Version: 1.0
Implementation-Title: My App
Implementation-Version: 1.4.2
Implementation-Vendor: Example Inc.

These fields are readable for a version page via getClass().getPackage().getImplementationVersion(). Have CI stamp the version so you can confirm exactly which build is live.

Friends & Partners