在tomcat7上发布springboot war包

来源:互联网 发布:windows性能测试工具 编辑:程序博客网 时间:2024/06/05 07:18

背景

最近公司在做一些内部的小型Web应用时, 为了提高开发效率决定使用SpringBoot, 这货自带Servlet容器, 
你在开发Web应用时可以直接在本地像运行控制台应用一样启动,省去了重复部署的时间;配置上相比于SpringMVC也是有了大大的简化。SpringBoot的应用可以直接打成一个可运行的jar包, 
你无需发愁为了不同应用要部署多个Tomcat。但是实际部署时你会发现打成Jar包的方式有一个致命的缺点, 
当你改动了一个资源文件、或者一个类时, 打要往服务器重新上传全量jar包。比如网速慢的公司(比如我们)来说, 那简直是不能忍受的!!!

还好SpringBoot也支持打包成普通的war包, 
这样你本地开发环境直接用控制台方式运行,部署到服务器时打成普通war包部署。这样既享受到了SpringBoot开发带来的快感, 
又避免了增量部署不方便的问题。可谓两全其美。 不过在打成War包时, 我也遇到了一些问题

问题描述

我修改pom.xml将打包方式改成war

<packaging>war</packaging>
  • 1
  • 1

完事儿打完包以后, 放到我本地Tomcat上跑了跑,发现没问题。但是部署到服务器上的Tomcat以后, 发现无法启动,错误如下:

org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/report]]        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1092)        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1984)        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)        at java.util.concurrent.FutureTask.run(FutureTask.java:262)        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)        at java.lang.Thread.run(Thread.java:745)Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;        at org.apache.tomcat.websocket.server.WsServerContainer.<init>(WsServerContainer.java:150)        at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)        at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47)        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5573)        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)        ... 10 more
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

明显不是应用代码错误,猜想应该是环境问题。经过分析, 我本地的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的版本无需指定了, 耶! ^_^


总结

总结下SpringBoot应用部署到Tomcat下的配置方法用于备忘也方便遇到同样问题的朋友

  1. 将打包方式改成war 
    这个没啥好说的, 肯定要改成war

  2. 配置嵌入Tomcat中的方式 
    这里有两种方式可选择:

    方式一:用spring-boot内置的tomcat库, 并指定你要部署到Tomcat的版本

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

    方式二:不用spring-boot内置的tomcat库(强烈推荐这种方式!!)

    <!-- 打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
  3. maven-war-plugin (可选) 
    与maven-resources-plugin类似,当你有一些自定义的打包操作, 比如有非标准目录文件要打到war包中或者有配置文件引用了pom中的变量。 具体用法参见官方文档:http://maven.apache.org/components/plugins/maven-war-plugin/

完!


经个人操作,方式一中,只需要

<properties><tomcat.version>7.0.69</tomcat.version></properties>

即可,

会自动覆盖spring-boot-starter-web下的tomcat版本。

打成的war包,放到webapps下,可直接访问

这中间可能还要注意mybatis-start和tomcat版本的冲突,mybaits支持的tomcat版本需要7.054以后(我用的7.054有问题,网上有人说7.069可以,不过我没试过),mybaits-start第一个版本是1.0.0吧好像,就不太支持tomcat7 的低版本,我直接升级到tomcat8了。就好了。

原创粉丝点击