
点击上方蓝字,关注我们吧
虽然官方推荐SpringBoot项目采用jar包方式发布,但是也可以打成war包发布到外部web容器(如Jetty,tomcat等)。接下来我们讨论一下,如何将一个SpringBoot项目打包成war包。
https://blog.csdn.net/weixin_40763897/article/details/105521123
参考:《Maven的约定》手工创建工程目录。当然,你绝对可以使用IDE来创建。
# 存放pom.xml和所有的子目录~/Desktop$ mkdir FlowerShop# 项目的java源代码~/Desktop/FlowerShop$ mkdir -p src/main/java# 创建包com.flower和com.flower.controller~/Desktop/FlowerShop$ mkdir -p src/main/java/com/flower/controller# 目录结构~/Desktop/FlowerShop$ tree -L 6.└── src└── main└── java└── com└── flower└── controller
这个目录对于我们将要演示的内容已经足够了。
~/Desktop/FlowerShop$ touch pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.flower</groupId><artifactId>FlowerShop</artifactId><version>1.0-SNAPSHOT</version><!--指定打包类型:pom,war,jar--><packaging>war</packaging><properties><java.version>1.8</java.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.6.RELEASE</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><!--指定打包的名称:FlowerShopDemo.war或FlowerShopDemo.jar--><finalName>FlowerShopDemo</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
~/Desktop/FlowerShop$ touch src/main/java/com/flower/MainApplicationStarter.java~/Desktop/FlowerShop$ vim src/main/java/com/flower/MainApplicationStarter.java
package com.flower;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.builder.SpringApplicationBuilder;@SpringBootApplicationpublic class MainApplicationStarter{public static void main(String[] args) {SpringApplication.run(MainApplicationStarter.class, args);}}
创建HomeController.java
~/Desktop/FlowerShop$ touch src/main/java/com/flower/controller/HomeController.java~/Desktop/FlowerShop$ vim src/main/java/com/flower/controller/HomeController.java
HomeController.java
package com.flower.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HomeController{@GetMapping("/home")public String getHomePage() {return "I Love you to come to my Flower Shop!";}}

~/Desktop/FlowerShop$ mvn spring-boot:run


SpringBoot项目创建成功!未对项目进行调整前,打出war包部署到Jetty9,启动会报错:
~/Documents/jetty-distribution-9.4.27.v20200227/bin$ ./jetty.sh start...2020-04-15 11:00:30.101:WARN:oejw.WebAppContext:main: Failed startup of context o.e.j.w.WebAppContext@a859c5{FlowerShopDemo,/FlowerShopDemo,file:///tmp/jetty-0_0_0_0-8888-FlowerShopDemo_war-_FlowerShopDemo-any-8018217352624732370.dir/webapp/,UNAVAILABLE}{/home/kyun/Documents/jetty-distribution-9.4.27.v20200227/webapps/FlowerShopDemo.war}java.util.ServiceConfigurationError: org.apache.juli.logging.Log: Provider org.eclipse.jetty.apache.jsp.JuliLog not a subtypeat java.util.ServiceLoader.fail(ServiceLoader.java:239)...
org.apache.juli.logging.Log: Provider org.eclipse.jetty.apache.jsp.JuliLog not a subtype:Jetty容器提供的JuliLog不是org.apache.juli.logging.Log的子类,这是由Jetty的加载机制造成的(直接部署到tomcat是没有这个问题的)。pom.xml作如下修改:
1
spring-boot-starter-web依赖中将tomcat排除
2
引入spring-boot-starter-jetty依赖
3
注释掉 spring-boot-maven-plugin插件
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.flower</groupId><artifactId>FlowerShop</artifactId><version>1.0-SNAPSHOT</version><!--指定打包类型pom, war, jar--><packaging>war</packaging><properties><java.version>1.8</java.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.6.RELEASE</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 移除嵌入式tomcat插件 --><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><!-- 引入Jetty依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId></dependency></dependencies><build><!--指定打包的名称:FlowerShopDemo.war或FlowerShopDemo.jar--><finalName>FlowerShopDemo</finalName><plugins><!--<plugin>--><!--<groupId>org.springframework.boot</groupId>--><!--<artifactId>spring-boot-maven-plugin</artifactId>--><!--</plugin>--></plugins></build></project>

做因为我们要用外部web容器启动项目,所以启动类必须继承SpringBootServletInitializer,并重写configure方法。如果使用内嵌的web容器则不需要继承SpringBootServletInitializer。

package com.flower;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;@SpringBootApplicationpublic class MainApplicationStarter extends SpringBootServletInitializer{public static void main(String[] args) {SpringApplication.run(MainApplicationStarter.class, args);}@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {// 注意这里要指向原先用main方法执行的Application启动类return builder.sources(MainApplicationStarter.class);}}

成功!
注意
SpringBoot项目官方推荐部署方式是jar包运行方式,即nohup java -jar xxx.jar &。
如果要用jar包方式部署,那么就要进行还原,但是不需要全部还原,只需添加回spring-boot-maven-plugin插件即可:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
Demo下载
https://github.com/wongkyunban/FlowerShop


扫一扫关注我们,
更多咨询早知道!




