Spring Boot默认提供内嵌的Tomcat,所以打包直接生成jar包,用Java -jar命令就可以启动。但是,有时候我们更希望一个Tomcat来管理多个项目,这种情况下就需要项目是war格式的包而不是jar格式的包。Spring Boot同样提供了解决方案,只需要简单的几步更改就可以了,这里提供Maven项目的解决方法:
1.将项目的启动类Application.java继承SpringBootServletInitializer并重写configure方法
@SpringBootApplication public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }2.在pom.xml文件中,project下面增加package标签
<packaging>war</packaging>3.还是在pom.xml文件中,dependencies下面添加
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>这样,只需要以上3步就可以打包成war包,并且部署到tomcat中了。需要注意的是这样部署的request url需要在端口后加上项目的名字才能正常访问。spring-boot更加强大的一点就是:即便项目是以上配置,依然可以用内嵌的tomcat来调试,启动命令和以前没变,还是:mvn spring-boot:run。
如果需要在springboot中加上request前缀,需要在application.properties中添加server.contextPath=/prefix/即可。其中prefix为前缀名。这个前缀会在war包中失效,取而代之的是war包名称,如果war包名称和prefix相同的话,那么调试环境和正式部署环境就是一个request地址了。
一般这样配置都不会出现问题,但有些时候,还是会报错,那是因为tomcat运行版本不同:
例如我在tomcat8.0.30版本下,配置如下:
<!-- 打war包时加入此项, 告诉spring-boot tomcat相关jar包用外部的,不要打进去 -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>1.4.0.RELEASE</version>
<scope>provided</scope>
</dependency>
这样配置在外部tomcat是8.0.30版本下正常运行,但是我的服务器是7.0.69就会报错:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/zhaolixiang]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:4088)
at org.apache.catalina.startup.HostConfig.reload(HostConfig.java:1539)
at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1512)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1748)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:333)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1371)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1543)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1553)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1521)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
at org.springframework.boot.context.web.SpringBootServletInitializer.createSpringApplicationBuilder(SpringBootServletInitializer.java:140)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:104)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:85)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5573)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 12 more
Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1858)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1701)
... 18 more
解决版本,修改代码: