如何创建 Spring Boot 应用程序并在 Tomcat 中将其作为 .war 运行? [复制]

Posted

技术标签:

【中文标题】如何创建 Spring Boot 应用程序并在 Tomcat 中将其作为 .war 运行? [复制]【英文标题】:How to create a Spring Boot application and run it as .war in Tomcat? [duplicate] 【发布时间】:2021-09-20 00:55:30 【问题描述】:

总结

我正在尝试从头开始创建一个基本的 Spring Boot 应用程序,构建一个 .war 文件并在 Tomcat 中运行它。我实现了在 Intellij 中运行它,但它没有在 Tomcat 中运行。

复制

我在下面解释如何重现我的问题。如果我遗漏任何相关内容,请发表评论。

如何创建项目?

使用以下选项在https://start.spring.io/ 上生成项目

点击按钮Generate。文件demo.zip 已下载。将其解压缩为目录demo。它应包含以下文件:

├── HELP.md
├── demo.iml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── demo
    │   │               ├── DemoApplication.java
    │   │               └── ServletInitializer.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       └── templates
    └── test
        └── java
            └── com
                └── example
                    └── demo
                        └── DemoApplicationTests.java

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication 

    public static void main(String[] args) 
        SpringApplication.run(DemoApplication.class, args);
    


src/main/java/com/example/demo/ServletInitializer.java

package com.example.demo;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer 

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) 
        return application.sources(DemoApplication.class);
    


src/main/resources/application.properties 为空


添加带有内容的文件src/main/java/com/example/demo/HelloWorldController.java

package com.example.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController 
    @RequestMapping("/")
    public String index() 
        return "Greetings from Spring Boot!";
    

如何在 Intellij 中运行项目?

在 Intellij 中打开并加载 maven 项目。在菜单中选择RunRun 'DemoApplication'。您应该在控制台中看到类似这样的内容:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.2)

2021-07-09 17:31:07.447  INFO 7245 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication using Java 1.8.0_292 on MY_HOST with PID 7245 (/path/to/demo/target/classes started by USER in /path/to/demo)
2021-07-09 17:31:07.451  INFO 7245 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2021-07-09 17:31:08.636  INFO 7245 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-07-09 17:31:08.647  INFO 7245 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-07-09 17:31:08.648  INFO 7245 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.48]
2021-07-09 17:31:08.720  INFO 7245 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-07-09 17:31:08.720  INFO 7245 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1205 ms
2021-07-09 17:31:09.214  INFO 7245 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-07-09 17:31:09.229  INFO 7245 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 2.89 seconds (JVM running for 3.783)

在浏览器中打开 http://localhost:8080/。你应该看到

Greetings from Spring Boot!

如何在 Intellij 中构建 .war?

在菜单中选择View &gt; Tool Windows &gt; Maven 并运行生命周期cleanpackage

在其他文件中,创建了一个文件target/demo-0.0.1-SNAPSHOT.war

如何在Tomcat中运行项目?

注意:我在下面使用 Docker 以使环境尽可能可重现。但是,我也尝试使用 brew 在另一台 Mac 上安装 Tomcat,但遇到了同样的问题。

在终端运行(在项目根目录下)

docker run --rm -p 8081:8080 \
  -v $PWD/target/demo-0.0.1-SNAPSHOT.war:/usr/local/tomcat/webapps/demo.war \
  tomcat:10-jdk8

你应该得到类似这样的输出:

09-Jul-2021 16:44:19.312 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/10.0.8
09-Jul-2021 16:44:19.315 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 25 2021 23:05:41 UTC
09-Jul-2021 16:44:19.315 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 10.0.8.0
09-Jul-2021 16:44:19.315 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
09-Jul-2021 16:44:19.315 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            5.10.25-linuxkit
09-Jul-2021 16:44:19.315 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
09-Jul-2021 16:44:19.316 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/openjdk-8/jre
09-Jul-2021 16:44:19.316 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.8.0_292-b10
09-Jul-2021 16:44:19.316 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
09-Jul-2021 16:44:19.316 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
09-Jul-2021 16:44:19.316 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
09-Jul-2021 16:44:19.320 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
09-Jul-2021 16:44:19.320 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
09-Jul-2021 16:44:19.320 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
09-Jul-2021 16:44:19.320 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
09-Jul-2021 16:44:19.321 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
09-Jul-2021 16:44:19.321 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
09-Jul-2021 16:44:19.321 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
09-Jul-2021 16:44:19.321 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
09-Jul-2021 16:44:19.321 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
09-Jul-2021 16:44:19.335 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded Apache Tomcat Native library [1.2.30] using APR version [1.6.5].
09-Jul-2021 16:44:19.335 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true].
09-Jul-2021 16:44:19.339 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1d  10 Sep 2019]
09-Jul-2021 16:44:19.821 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
09-Jul-2021 16:44:19.844 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [769] milliseconds
09-Jul-2021 16:44:19.898 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
09-Jul-2021 16:44:19.898 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.0.8]
09-Jul-2021 16:44:19.945 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/demo.war]
09-Jul-2021 16:44:21.248 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
09-Jul-2021 16:44:21.315 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat/webapps/demo.war] has finished in [1,369] ms
09-Jul-2021 16:44:21.321 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
09-Jul-2021 16:44:21.339 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [1494] milliseconds

注意:我希望我的应用程序的日志,即

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.2)

...

这里也出现了,但是不见了。

在浏览器中打开 http://localhost:8081/demo/。我期待看到

Greetings from Spring Boot!

但我明白了


我的项目或 Tomcat 配置/代码中缺少什么?如何在 Tomcat 中将 Spring Boot 应用程序作为 .war 运行?

【问题讨论】:

这也是为什么Docker镜像tomcat:latest是一个运行在OpenJDK 11 JVM上的Tomcat 9.0的原因。 ***.com/a/66808062/104891 是否解释了为什么使用 Tomcat 10 会得到 404? @piotr-p-karwasz 是的,使用 tomcat:9-jdk8 而不是 tomcat:10-jdk8 正在工作。非常感谢:) @CrazyCoder 感谢您指出解释。 @maiermic:日志可能是空的,因为 Spring 使用 javax.servlet.ServletContainerInitializer。由于 Tomcat 10 不处理它,您可能会注意到的唯一一件事就是缺少日志。 【参考方案1】:

正如 cmets 中指出的那样,运行 Tomcat 9 而不是 10 可以工作

docker run --rm -p 8081:8080 \
  -v $PWD/target/demo-0.0.1-SNAPSHOT.war:/usr/local/tomcat/webapps/demo.war \
  tomcat:9-jdk8

【讨论】:

以上是关于如何创建 Spring Boot 应用程序并在 Tomcat 中将其作为 .war 运行? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 Spring Boot 中的活动配置文件设置注释属性值?

Docker 容器整合 Spring Boot 应用

如何在spring boot中的每个测试类之后销毁和重新创建bean

如何设置letsencrypt SSL证书并在Spring Boot应用程序中使用它?

如何将购物车项目存储在 localStorage 中并在 Spring Boot 中使用 AJAX 显示该项目?

如何在spring boot中实现jms队列