首页 文章

Spring Boot War部署到Tomcat

提问于
浏览
63

我正在尝试将Spring Boot应用程序部署到Tomcat,因为我想部署到AWS . 我创建了一个WAR文件,但它似乎不在Tomcat上运行,即使它是可见的 .

细节:
这是我的应用程序:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class App {
    public static void main(String[] args) {
        SpringApplication.run(SampleController.class, args);
    }
}

@Controller
@EnableAutoConfiguration
public class SampleController {
    @RequestMapping("/help")
    @ResponseBody
    String home() {
        String input = "Hi! Please use 'tag','check' and 'close' resources.";
        return input;
    }
}

application.properties有以下内容:

server.port=${port:7777}

http://maven.apache.org/xsd/maven-4.0.0.xsd“> 4.0.0

<groupId>com.niewlabs</groupId>
<artifactId>highlighter</artifactId>
<version>1.0-SNAPSHOT</version>

<packaging>war</packaging>

<properties>
    <java.version>1.8</java.version>
</properties>    
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.9.RELEASE</version>
</parent>    
<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>
</dependencies>
  • 我运行了“mvn package”并获得了WAR文件(大小为250Mb),我将其放入“webapps”文件夹中 .

  • 我启动了Tomcat,并且能够看到我的应用程序列出,在我的情况下"/highlighter-1.0-SNAPSHOT" .

  • 单击应用程序的链接将导致"Status 404"页面 .

  • 当我单独运行Spring Boot应用程序时,没有容器它在localhost:7777上运行,但是当我在Tomcat中运行它时没有任何东西 .

更新:还有另一个reference . 不确定它有多有用 .

10 回答

  • 0

    本指南详细说明了如何在Tomcat上部署Spring Boot应用程序:
    http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file

    基本上我需要添加以下类:

    public class WebInitializer extends SpringBootServletInitializer {   
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(App.class);
        }    
    }
    

    我还将以下属性添加到POM:

    <properties>        
        <start-class>mypackage.App</start-class>
    </properties>
    
  • 3

    我觉得你对这里的不同范式感到困惑 . 首先,war文件和服务器部署 - 这些东西属于Java Enterprise Edition(Java EE) . 这些概念在spring-boot应用程序中没有实际位置,它遵循不同的模型 .

    Spring-boot负责创建嵌入式容器并直接从标准jar文件中运行您的服务(尽管它可以做更多) . 我认为这个模型的目的是支持微服务开发 - 每个服务都有自己的容器,完全是自包含的 . 您也可以使用您的代码生成Java EE应用程序,但考虑到spring-boot更容易(对于某些类型的应用程序/服务),这将是愚蠢的 .

    因此,根据这些信息,您现在必须决定您将遵循的范例,并且您需要遵循这一点,而且只需遵循 .

    Spring-boot是可执行的 - 您只需在App类中运行main方法,您可以从命令行或使用您喜欢的IDE或maven或gradle(提示:maven是正确的答案) . 这将打开一个tomcat服务器(默认情况下),您的服务将在其中可用 . 鉴于您在上面发布的配置应该在以下位置提供: http://localhost:7777/context/help - context 应替换为您尚未共享的上下文名称 .

    您不是要创建战争,运行tomcat或部署任何东西 . 在spring-boot中没有必要这样做 . 你的pom中的包装应该 jar ,而不是 warspring-boot-starter-tomcatscope 应该被删除 - 当然没有提供 .

    运行main方法时,控制台输出应该告诉您已注册的上下文;用它来获取正确的URL .

    说了这么多,spring-boot现在必须存在于JEE世界中(直到它被广泛采用) . 出于这个原因,spring人员已经记录了构建war而不是可执行jar的方法,以便部署到servlet或JEE容器 . 这允许许多 spring 引导技术用于除了战争(或耳朵)之外的任何限制使用的环境中 . 然而,这仅仅是对这种环境非常普遍的事实的回应,并且不被视为解决方案的必要或甚至是期望的部分 .

  • 2

    嘿,请确保对pom.xml进行此更改

    <packaging>war</packaging>
    

    在依赖项部分,请确保指示提供了tomcat,因此您不需要嵌入式tomcat插件 .

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>       
    
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
    

    这是整个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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <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>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.4.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <start-class>com.example.Application</start-class>
        </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-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <scope>provided</scope>
            </dependency>       
    
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-jasper</artifactId>
                <scope>provided</scope>
            </dependency>       
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    

    Application类应该是这样的

    Application.java

    package com.example;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.support.SpringBootServletInitializer;
    
    @SpringBootApplication
    public class Application extends SpringBootServletInitializer {
    
    
        /**
         * Used when run as JAR
         */
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        /**
         * Used when run as WAR
         */
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
            return builder.sources(Application.class);
        }
    
    }
    

    您可以添加一个控制器来测试MyController.java

    package com.example;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    public class MyController {
    
        @RequestMapping("/hi")
        public @ResponseBody String hiThere(){
            return "hello world!";
        }
    }
    

    然后你可以在tomcat 8版本中运行项目并像这样访问控制器

    http://localhost:8080/demo/hi

    如果由于某种原因您无法将项目添加到tomcat,请在项目中右键单击,然后转到Build Path-> configure build path-> Project Faces

    确保只选择了这3个

    动态Web模块3.1 Java 1.8 Javascript 1.0

  • 19

    你的 Application.java 类应扩展 SpringBootServletInitializer 类ex:

    public class Application extends SpringBootServletInitializer {}
    
  • 2

    在遵循指南(或使用Spring Initializr)之后,我有一个可在我的本地计算机上运行的WAR,但是无法远程工作(在Tomcat上运行) .

    没有错误消息,它只是说“发现了Spring servlet初始化程序”,但根本没有做任何事情 .

    17-Aug-2016 16:58:13.552 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.4
    17-Aug-2016 16:58:13.593 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /opt/tomcat/webapps/ROOT.war
    17-Aug-2016 16:58:16.243 INFO [localhost-startStop-1] 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.
    

    17-Aug-2016 16:58:16.301 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath
    17-Aug-2016 16:58:21.471 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
    17-Aug-2016 16:58:25.133 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log ContextListener: contextInitialized()
    17-Aug-2016 16:58:25.133 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log SessionListener: contextInitialized()
    

    没有其他事情发生 . Spring Boot刚刚没有运行 .

    显然我使用Java 1.8编译服务器,远程计算机使用Java 1.7 .

    在使用Java 1.7编译之后,它开始工作了 .

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.7</java.version> <!-- added this line -->
        <start-class>myapp.SpringApplication</start-class>
    </properties>
    
  • 0

    我有同样的问题,我按照这个guide找到解决方案 . 我在maven中以目标跑 .

    干净的包裹

    它为我的Thanq工作

  • 1

    使用Gradle的人的解决方案

    添加插件到 build.gradle

    apply plugin: 'war'
    

    provided 依赖tomcat

    dependencies {
        // other dependencies
        providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    }
    
  • 15

    公共类应用程序扩展SpringBootServletInitializer {}

    只是扩展了SpringBootServletInitializer . 它适用于您的AWS / tomcat

  • 2

    如果您的目标是 deploy your Spring Boot application to AWSBoxfuse为您提供了一个非常简单的解决方案 .

    您需要做的就是:

    boxfuse run my-spring-boot-app-1.0.jar -env=prod
    

    这将:

    • 为您的应用程序量身定制最小的操作系统映像(比典型的Linux发行版小约100倍)

    • 将其推送到安全的在线存储库

    • 在大约30秒内将其转换为AMI

    • 创建并配置新的弹性IP或ELB

    • 为其分配新域名

    • 根据您的新AMI启动一个或多个实例

    所有图像都在几秒钟内生成,并且是不可变的 . 它们可以在VirtualBox(dev)和AWS(test&prod)上保持不变 .

    所有更新都以 zero-downtime blue/green deployments 执行,您还可以使用一个命令启用自动缩放 .

    Boxfuse也明白你的Spring Boot配置会 automatically configure security groups and ELB health checks based upon your application.properties .

    这是一个帮助您入门的教程:https://boxfuse.com/getstarted/springboot

    免责声明:我是Boxfuse的创始人兼首席执行官

  • 90

    使用Spring Boot 1.5.8.RELEASE更新2018-02-03 .

    在pom.xml中,你需要告诉Spring插件,当它构建一个war文件时,通过change package to war,如下所示:

    <packaging>war</packaging>
    

    此外,您必须通过添加以下内容来构建包时排除嵌入式tomcat:

    <!-- to deploy as a war in tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    

    完整的可运行示例在这里https://www.surasint.com/spring-boot-create-war-for-tomcat/

相关问题