一、简介

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

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

二、直接将SpringBoot打成war包

  1. 创建一个SpringBoot web项目,并修改打包方式和端口
  • 启动类
@SpringBootApplication
public class CcSpringBootWarApplication {

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

}
  • pom.xml
<groupId>cc.lu</groupId>
<artifactId>cc-spring-boot-war</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 添加packaging并指明方式为war -->
<packaging>war</packaging>
  • 修改端口,不要和tomcat的8080冲突,修改tomcat的也可以
server.port=8990

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

  1. 创建一个API
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";
    }

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

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

springboot打成war能用启动命令启动吗 springboot war包运行_spring boot

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

三、优化后的SpringBoot打war包

  1. 修改依赖的tomcat包的scope
  • 第一种方式
<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,不然打包的时候会报错。

  • 第二种方式
<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便于打包。

  1. 修改启动类,设置启动配置
    发布到独立的Tomcat需要继承SpringBootServletInitializer类并重写configure方法,在war包部署解压后的文件夹中没有普通web项目的web.xml,但是仍然能启动,就是因为SpringConfig继承了SpringBootServletInitializer,所以打包的时候SpringBoot做了初始化工作,这个类就是用于代替传统MVC模式中的web.xml。
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);
    }
}
  1. 打包
mvn clean install -Dmaven.test.skip=true
  1. 部署
    将war包放到外部tomcat的webapps目录下,然后启动tomcat后访问http://127.0.0.1/boot-war/cc,访问正常。

四、直接创建war项目

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

springboot打成war能用启动命令启动吗 springboot war包运行_maven_02

创建的应用内容如下:

springboot打成war能用启动命令启动吗 springboot war包运行_war包_03