先说遇到问题的情景:

初次尝试使用spring boot框架写了个小web项目,在Intellij IDEA中能正常启动运行。使用maven 运行install,生成war包,发布到本机的tomcat下,出现异常,主要的异常信息是  .......LifeCycleException。经各种搜索,找到答案。


spring boot因为内嵌tomcat容器,所以可以通过打包为jar包的方法将项目发布,但是如何将spring boot项目打包成可发布到tomcat中的war包项目呢?

1. 既然需要打包成war包项目,首先需要在pom.xml文件中修改打包类型,将spring boot默认的<packaging>jar</packaging>修改为<packaging>war</packaging>形式;

2. 其次spring boot的web项目中内嵌tomcat服务器,所以如果我们想要发布war包到tomcat项目,要讲spring boot中内嵌的tomcat包依赖排除,不然产生冲突,打开下面代码中的注释即可。

1
2
3
4
5
6
7
8
9
10
11
12
< 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 >           

有一点想说的是,如果本地开发的时候依然想要使用spring boot内嵌tomcat进行调试,添加如下依赖即可;

1
2
3
4
5
< dependency >
     < groupId >org.springframework.boot</ groupId >
     < artifactId >spring-boot-starter-tomcat</ artifactId >
     < scope >provided</ scope >
</ dependency >

3. spring boot发布jar包web程序的入口是main函数所在的类,使用@SpringBootApplication注解。但是如果war包发布至tomcat,需要增加 SpringBootServletInitializer 子类,并覆盖它的 configure 方法,或者直接将main函数所在的类继承 SpringBootServletInitializer 子类,并覆盖它的 configure 方法。代码举例如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@SpringBootApplication
public  class  DemoApplication  extends  SpringBootServletInitializer {
     
     @Override
     protected  SpringApplicationBuilder configure(
             SpringApplicationBuilder application) {
         return  application.sources(DemoApplication. class );
     }
 
     
     public  static  void  main(String[] args) {
         SpringApplication.run(DemoApplication. class , args);
     }
}



以上就完成了spring boot项目打包war包的所有步骤,可以发布至tomcat7及其以上版本。


最后还有最重要的一点,如果你本机的tomcat版本和  springboot自动集成的8.0版本不一致。也会出问题,解决办法 :

我本地的Tomcat版本是8.0.28, 而服务器上的Tomcat是7.0.69。 我在本地下了个Tomcat7.0.70部署也报同样错误。更加确定问题跟Tomcat版本有关。经过多方查找资料,最后在Stackoverflow上看到一个老外说SpringBoot默认Servlet容器是基于Tomcat8的

在打好的war包中确实发现了Tomcat相关jar包,而且是Tomcat8的,拿Tomcat8的embed包在Tomcat7下面那肯定是不能用啊 
这里写图片描述

要支持低版本Tomcat需要在maven中指定Tomat版本,配置如下:

<properties>
    <tomcat.version>7.0.69</tomcat.version>
</properties>
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

然后依赖中加上(这个其实不加也行, 官方文档是加上的)

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-juli</artifactId>
    <version>${tomcat.version}</version>
</dependency>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

加上以后试了下,果然是没问题了。看了下war包中的lib目录,确实已经变成Tomcat7的包了 
这里写图片描述

但是我还是有点疑惑, 这样配置打成包岂不是换个Tomcat版本就要重新打次包? 既然是由于SpringBoot内部的Servlet容器造成了这个限制, 那我不用行不行? 又查了很多资料, 还真有办法!

<!-- 打war包时加入此项, 告诉spring-boot tomcat相关jar包用外部的,不要打进去 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

试了下, 加上这个后, 上面说Tomcat的版本无需指定了, 耶! ^_^




Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐