SpringBoot如何以war包形式运行

一、简介

SpringBoot应用默认打包成可执行jar模式方便我们的快速部署,如果是web应用的话,则默认使用内置的tomcat作为servlet容器,但是如果我们需要根据业务特性对容器做一些特殊配置,那么SpringBoot内置的tomcat容器就无法满足我们了,因此我们就需要把SpringBoot应用打包成war包,让其能够在外部tomcat中运行。

那我们直接打成war包然后部署到tomcat是否可行?我们来试下,看看会发生什么。

二、直接将SpringBoot打成war包

  1. 创建一个SpringBoot web项目,并修改打包方式和端口

    • 启动类

      1
      2
      3
      4
      5
      6
      7
      8
      @SpringBootApplication
      public class CcSpringBootWarApplication {

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

      }
    • pom.xml

      1
      2
      3
      4
      5
      <groupId>cc.lu</groupId>
      <artifactId>cc-spring-boot-war</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <!-- 添加packaging并指明方式为war -->
      <packaging>war</packaging>
    • 修改端口,不要和tomcat的8080冲突,修改tomcat的也可以

      1
      server.port=8990

    以上就是我们创建的一个简单的SpringBoot应用所具有的东西

  2. 创建一个API

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;

    @RestController
    public class MyController {

    @GetMapping("/cc")
    public String test1() {
    return "cc";
    }

    }
  3. 打包

    1
    mvn clean install -Dmaven.test.skip=true
  4. 放到tomcat中启动,查看控制台信息

    image-20200426212704488

    没有报错,那么我们访问一下接口http://127.0.0.1/boot-war/cc,报了404,说明我们项目未被部署成功。

    image-20200426212841507

未部署成功,是因为我们在打包的时候,将内置的tomcat的jar包一并打到war包中了,这时和外部的tomcat冲突了。

三、优化后的SpringBoot打war包

  1. 修改依赖的tomcat包的scope

    • 第一种方式

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
      <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      </exclusion>
      </exclusions>
      </dependency>

      <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <scope>provided</scope>
      </dependency>

      直接屏蔽掉spring-boot-starter-web中向下传递的spring-boot-starter-tomcat包,并引入javax.servlet-api包,并将scope设置为provided,不然打包的时候会报错。

    • 第二种方式

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      <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>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <scope>provided</scope>
      </dependency>

      spring-boot-starter-tomcatjavax.servlet-api的jar包的scope设置为provided便于打包。

  2. 修改启动类,设置启动配置

    发布到独立的Tomcat需要继承SpringBootServletInitializer类并重写configure方法,在war包部署解压后的文件夹中没有普通web项目的web.xml,但是仍然能启动,就是因为SpringConfig继承了SpringBootServletInitializer,所以打包的时候SpringBoot做了初始化工作,这个类就是用于代替传统MVC模式中的web.xml。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

    @SpringBootApplication
    public class CcSpringBootWarApplication extends SpringBootServletInitializer {

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(CcSpringBootWarApplication.class);
    }
    }
  3. 打包

    1
    mvn clean install -Dmaven.test.skip=true
  4. 部署

    将war包放到外部tomcat的webapps目录下,然后启动tomcat后访问http://127.0.0.1/boot-war/cc,访问正常。

    image-20200426215949343

四、直接创建war项目

在创建应用的时候,packaging选择War(目前只有Jar和War两个选项),就能直接创建出符合条件的应用,不需要再进行任何修改就可以直接打成war包。

image-20200426220404239

创建的应用内容如下:

image-20200426220312800