Servlet 包
war 的结构、MANIFEST、打包命令与部署方式。
war 的结构
myapp.war
├── index.jsp
├── css/
├── js/
├── images/
├── META-INF/
│ └── MANIFEST.MF
└── WEB-INF/
├── web.xml
├── classes/
│ └── com/example/HelloServlet.class
└── lib/
└── mysql-connector-j.jarA 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 打包
<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>mvn clean package[INFO] Building war: target/myapp.war
[INFO] BUILD SUCCESS用 jar 命令打包
# 在 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.
部署方式
| Method | How | When |
|---|---|---|
| Copy to webapps | 把 war 放进 webapps/,容器自动解压部署 | 简单、单机 |
| Context descriptor | 在 conf/Catalina/localhost/ 放 myapp.xml 指向 war | war 放外部目录 |
| Manager app | 浏览器登录 Manager 上传 war | 远程部署 |
| Embedded | Spring Boot 打成可执行 jar,java -jar | 现代主流 |
myapp.war serves at /myapp. For the root path, name it ROOT.war or set path="" in the context descriptor.MANIFEST 里值得写的
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.
war 的结构
myapp.war
├── index.jsp
├── css/
├── js/
├── images/
├── META-INF/
│ └── MANIFEST.MF
└── WEB-INF/
├── web.xml
├── classes/
│ └── com/example/HelloServlet.class
└── lib/
└── mysql-connector-j.jarwar 本质是 zip。容器解压后,WEB-INF/classes 进类加载器,WEB-INF/lib 里的 jar 也进类加载器,WEB-INF 之外的文件直接对外提供。
用 Maven 打包
<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>mvn clean package[INFO] Building war: target/myapp.war
[INFO] BUILD SUCCESS用 jar 命令打包
# 在 webapp 目录下执行
jar -cvf myapp.war .jar 命令只做压缩,不编译、不拷依赖。class 文件和 jar 依赖得自己先放进 WEB-INF/classes 与 WEB-INF/lib,所以实际项目都用 Maven 或 Gradle。
部署方式
| 方式 | 做法 | 适用 |
|---|---|---|
| 拷到 webapps | 把 war 放进 webapps/,容器自动解压部署 | 简单、单机 |
| 上下文描述符 | 在 conf/Catalina/localhost/ 放 myapp.xml 指向 war | war 放外部目录 |
| 管理台 | 浏览器登录 Manager 上传 war | 远程部署 |
| 内嵌容器 | Spring Boot 打成可执行 jar,java -jar | 现代主流 |
myapp.war 就是 /myapp。想部署到根路径,命名为 ROOT.war,或在上下文描述符里写 path=""。MANIFEST 里值得写的
Manifest-Version: 1.0
Implementation-Title: My App
Implementation-Version: 1.4.2
Implementation-Vendor: Example Inc.这些字段可以用 getServletContext().getServerInfo() 之外的方式读到,做版本页很方便:getClass().getPackage().getImplementationVersion()。CI 构建时自动写入版本号,排查线上问题一眼就能确认部署的是哪个包。