IntelliJ IDEA SpringBoot 使用第三方Tomcat以及部署

花了半天時間終於成功,記錄以備查閱。

一、第三方Tomcat部署

部署部分參考的是:把spring-boot項目部署到tomcat容器中

目標:把spring-boot項目按照平常的web項目一樣發佈到tomcat容器下

1. 修改打包形式

在pom.xml裏設置 <packaging>war</packaging>

<groupId>com.study</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

2. 移除嵌入式tomcat插件

在pom.xml裏找到spring-boot-starter-web依賴節點,在其中添加如下代碼:

複製代碼

<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>

複製代碼

3. 添加servlet-api的依賴

下面兩種方式都可以,任選其一

<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>

4. 修改啓動類,並重寫初始化方法

我們平常用main方法啓動的方式,都有一個App的啓動類,代碼如下:

@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);
    }
}

複製代碼

5. 打包部署

複製代碼

在項目根目錄下(即包含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:[端口號]/[打包項目名]/

發佈成功

複製代碼

二、IntelliJ IDEA下使用第三方Tomcat運行項目

1. 完成部署中的1,2,3,4步驟

2. 配置第三方Tomcat

IDEA上方工具欄:Run->Edit Configurations

打開配置界面,左邊"+"號->Tomcat Server->Local

完成後如下所示

然後在Deployment中點擊"+"號,選擇client:war,這樣每次server啓動的時候都會去打包一次war包(個人理解),然後去運行war包。

然後保存就可以了,然後啓動項目就運行起來了。

三、部署中遇到的問題

1. log4j.properties中使用了環境變量

log4j.appender.dailyFile.File=${catalina.base}/logs/guandata/log.log4j

在啓動第三方Tomcat時,Tomcat會去環境變量中尋找叫CATALINA_HOME、CATALINA_BASE的環境變量,並將它們加入到Tomcat到系統變量中,這樣我們就能在項目中使用它們了。

2. 部署後訪問靜態資源,訪問路徑URL中多了項目名,導致靜態資源找不到

舉例:

原本在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">

這樣就能正確訪問到靜態資源啦。

3. 要注意給Tomcat/bin路徑下的腳本權限,否則可能會出現不可預料的後果

sudo chmod 777 /Library/Tomcat/apache-tomcat-9.0.10/bin/*.sh

博客內容均爲本人學習記錄,不保證一定正確,如果錯誤,歡迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章