花了半天時間終於成功,記錄以備查閱。css
部署部分參考的是:把spring-boot項目部署到tomcat容器中前端
目標:把spring-boot項目按照日常的web項目同樣發佈到tomcat容器下java
在pom.xml裏設置 <packaging>war</packaging>web
<groupId>com.study</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
在pom.xml裏找到spring-boot-starter-web
依賴節點,在其中添加以下代碼:spring
<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>
下面兩種方式均可以,任選其一apache
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>8.0.36</version> <scope>provided</scope> </dependency>
咱們日常用main方法啓動的方式,都有一個App的啓動類,代碼以下:bootstrap
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
直接讓啓動類繼承SpringBootServletInitializer,並覆蓋configure()方法:後端
@SpringBootApplication public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { // 注意這裏要指向原先用main方法執行的Application啓動類 return builder.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
在項目根目錄下(即包含pom.xml的目錄),在命令行裏輸入: mvn clean package便可, 等待打包完成,出現[INFO] BUILD SUCCESS即爲打包成功。 mvn clean package 命令能夠按須要添加參數, -DskipTests 不執行測試用例,但編譯測試用例類生成相應的class文件至target/test-classes下。 -Dspring.profiles.active=dev 若是配置了多環境,能夠設置打包到哪一個環境。 而後把target目錄下的war包放到tomcat的webapps目錄下,啓動tomcat,便可自動解壓部署。 最後在瀏覽器中輸入 http://localhost:[端口號]/[打包項目名]/ 發佈成功
IDEA上方工具欄:Run->Edit Configurationsapi
打開配置界面,左邊"+"號->Tomcat Server->Local瀏覽器
完成後以下所示
而後在Deployment中點擊"+"號,選擇client:war,這樣每次server啓動的時候都會去打包一次war包(我的理解),而後去運行war包。
而後保存就能夠了,而後啓動項目就運行起來了。
log4j.appender.dailyFile.File=${catalina.base}/logs/guandata/log.log4j
在啓動第三方Tomcat時,Tomcat會去環境變量中尋找叫CATALINA_HOME、CATALINA_BASE的環境變量,並將它們加入到Tomcat到系統變量中,這樣咱們就能在項目中使用它們了。
舉例:
本來在springboot內置Tomcat中運行項目,資源訪問路徑URL相似於:http://localhost:8080/css/bootstrap.min.css 可是打包部署到第三方Tomcat中,Tomcat默認會在路徑中加上項目名,相似於:http://localhost:8080/myproject/css/bootstrap.min.css 這樣就致使了訪問不到靜態資源 404
緣由:
因爲在前端引用資源時使用了絕對路徑:
<link href="/css/bootstrap.min.css" rel="stylesheet">
這樣默認在 http://localhost:8080/css/bootstrap.min.css 下面尋找,所以,咱們須要在前面加上項目名,可是寫死的話萬一改項目名就很麻煩,固然是有辦法解決的。
解決:
1. 在Java後端定義一個攔截器,用來獲取 request.getContextPath() 而後傳到前端,request.getContextPath() 獲得的是項目的根路徑,具體參考:關於request.getServletPath(),request.getContextPath()的總結
1 @Component 2 public class CommonIntercepter implements HandlerInterceptor { 3 4 private final Logger logger = LoggerFactory.getLogger(this.getClass()); 5 6 @Override 7 public boolean preHandle(HttpServletRequest request, 8 HttpServletResponse response, Object handler) throws Exception { 9 return true; 10 } 11 12 @Override 13 public void postHandle(HttpServletRequest request, 14 HttpServletResponse response, Object handler, 15 ModelAndView modelAndView) throws Exception { 16 request.setAttribute("ctx", request.getContextPath()); 17 request.setAttribute("version", DateTimeUtils.currentTimeMillis()); 18 } 19 20 @Override 21 public void afterCompletion(HttpServletRequest request, 22 HttpServletResponse response, Object handler, Exception ex) 23 throws Exception { 24 25 } 26 27 28 }
2. 前端在靜態資源訪問url前加上${ctx!},注意我用的是freemarker模版
<link href="${ctx!}/css/bootstrap.min.css" rel="stylesheet"> <link href="${ctx!}/css/font-awesome.min.css" rel="stylesheet"> <link href="${ctx!}/css/plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet"> <link href="${ctx!}/css/animate.css" rel="stylesheet"> <link href="${ctx!}/css/style.css" rel="stylesheet">
這樣就能正確訪問到靜態資源啦。
sudo chmod 777 /Library/Tomcat/apache-tomcat-9.0.10/bin/*.sh