一、前言
SpringBoot内置tomcat使用很方便,打包成可执行jar文件后可以直接运行,然后内置Tomcat配置终究没有外部独立Tomcat方便,并且如果有多个web应用,使用外部独立Tomcat管理起来也更加方便。因此,这边文章介绍一下本人将myblog应用部署到外部Tomcat的过程以及其中遇到的一些问题与解决方法。
二、打包成可部署到Tomcat的war包
将应用打成war包,需要进行以下几个步骤:
1.修改打包形式
将原来的jar打包形式<packaging>jar</packaging>
改成war打包形式<packaging>war</packaging>
。打jar包的插件仍然可以保留,不冲突。
2.移除嵌入式tomcat插件
在pom.xml里找到spring-boot-starter-web依赖节点,在其中添加如下代码:
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-web</artifactId> 4 <!-- 移除嵌入式tomcat插件 --> 5 <exclusions> 6 <exclusion> 7 <groupId>org.springframework.boot</groupId> 8 <artifactId>spring-boot-starter-tomcat</artifactId> 9 </exclusion> 10 </exclusions> 11 </dependency>
3.将Tomcat依赖修改为本地调试模式
为了本地调试方便,在pom.xml文件中,dependencies下面的tomcat依赖修改为:
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-web</artifactId> 4 <exclusions> 5 <exclusion> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-starter-tomcat</artifactId> 8 </exclusion> 9 </exclusions> 10 </dependency>
4.修改启动类
常规Springboot应用启动类为Application:
1 package com.guigui.blog; 2 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 import org.springframework.cache.annotation.EnableCaching; 5 import org.springframework.transaction.annotation.EnableTransactionManagement; 6 @SpringBootApplication 7 @EnableTransactionManagement 8 @EnableCaching 9 public class Application { 10 public static void main(String[] args) { 11 SpringApplication.run(Application.class, args); 12 } 13 }
我们需要类似于web.xml的配置方式来启动spring上下文,在Application类的同级添加一个SpringBootStartApplication类,其代码如下:
1 package com.guigui.blog; 2 import org.springframework.boot.builder.SpringApplicationBuilder; 3 import org.springframework.boot.web.support.SpringBootServletInitializer; 4 /** 5 * 修改启动类,继承 SpringBootServletInitializer 并重写 configure 方法 6 */ 7 public class SpringBootStartApplication extends SpringBootServletInitializer { 8 @Override 9 protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 10 // 注意这里要指向原先用main方法执行的Application启动类 11 return builder.sources(Application.class); 12 } 13 }
5.打包部署
在项目根目录下(即包含pom.xml的目录),在命令行里输入:
1 mvn clean package
即可, 等待打包完成,出现[INFO] BUILD SUCCESS即为打包成功。然后把target目录下的war包放到tomcat的webapps目录下,启动tomcat,即可自动解压部署。 最后在浏览器中输入:
http://localhost:[端口号]/[打包项目名]/
发布成功。
三、遇到问题
1.访问路径问题
部署到外部tomcat之后,请求的URL需要在端口号加上项目名才可以正常访问,这样页面中各种资源的访问都需要加上相应的项目名称,为了保证常规Springboot应用访问资源也不会出现问题,需要将Springboot应用配置为带项目名前缀访问,application.yml文件改动:
1 server: 2 context-path: /myblog
这样两种方式的请求URL就是一样的了。
由于项目名称通过具体的部署情况,名称可能不一样,所以在js或者ftl等页面文件中使用的项目名称不能写死,需要动态获取,下面给出js和ftl文件动态获取项目名称方式:
- 1.ftl获取当前项目名称:
1 <#assign basePath=request.contextPath> 2 <!-- 具体使用 --> 3 <link href="${basePath}/vendor/admin/bootstrap/css/bootstrap.min.css" rel="stylesheet">
- 2.js中获取当前项目名称:
1 function getRootPath() { 2 var strPath = window.document.location.pathname; 3 var postPath = strPath.substring(0, strPath.substr(1).indexOf('/') + 1); 4 return postPath; 5 }
2.字体资源无法访问导致icon图标显示失败问题
Spring Boot + Bootstrap 出现"Failed to decode downloaded font"和"OTS parsing error: Failed to convert W
错误。导致所有图标显示不出。
通过各种百度和Google搜索,找到原因:
因为经过maven的filter,会破坏font文件的二进制文件格式,到时前台解析出错。
解决方案:
设置filter,font文件不需要filter,具体pom文件配置如下:
1 <resource> 2 <directory>src/main/resources</directory> 3 <targetPath>${basedir}/target/classes</targetPath> 4 <filtering>true</filtering> 5 <excludes> 6 <exclude>static/vendor/**/fonts/**</exclude> 7 </excludes> 8 </resource> 9 <resource> 10 <directory>src/main/resources</directory> 11 <targetPath>${basedir}/target/classes</targetPath> 12 <filtering>false</filtering> 13 <includes> 14 <include>static/vendor/**/fonts/**</include> 15 </includes> 16 </resource>
重新编译整个工程,解决问题。