SpringBoot使用IDEA設定的外部Tomcat啟動,遇到的問題和解決

JoKKKKKKKKKKKKK發表於2019-08-12


外部Tomcat

springboot 專案部署到外部tomcat
Spring Boot:內建tomcat啟動和外部tomcat部署總結
網上的部署到外部Tomcat的例子足夠多,這裡精簡步驟,方便記憶。

1. 改成war方式打包

在 pom.xml 設定:

<packaging>war</packaging>
    <build>
        <plugins>
<!-- 把原來的 spring-boot-maven-plugin 註釋掉/刪掉-->

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
            </plugin>

        </plugins>
        <finalName>springbootdemo</finalName>
    </build>

2. 移除對SpringBoot中的嵌入式Tomcat的依賴

  • 需要移除對嵌入式Tomcat的依賴,這樣打出的war包中,在lib目錄下才不會包含Tomcat相關的jar包,否則將會出現啟動錯誤。
  • 因為SpringBootServletInitializer需要依賴 javax.servlet,而tomcat-embed-jasper下面的 tomcat-embed-core 中就有這個 javax.servlet,如果沒用provided,最終打好的war裡面會有servlet-api這個jar,這樣就會跟tomcat本身的衝突了。
    還有一個很關鍵,就是tomcat-embed-jasper中scope必須是provided。

在 pom.xml 新增:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

3. 修改SpringBoot的啟動類

  • 修改啟動類,使其繼承SpringBootServletInitializer類,重寫configure方法。
  • 如果SpringBoot幫我們建立了SpringBootServletInitializer類檔案,直接刪掉,修改最開始的SpringBootApplication 專案啟動類,就是有main方法的那個。
@SpringBootApplication
@ServletComponentScan
@ComponentScan(basePackages = {"com.example.controller", "com.example.service"})
@MapperScan(basePackages = {"com.example.dao"})
public class SpringbootdemoApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringbootdemoApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringbootdemoApplication.class, args);
    }
}

注:根據情況,可以在 pom.xml 修改打包名稱

<build>
    <finalName>springbootdemo</finalName>
</build>

4. 在IDEA裡用外部Maven打包,用外部Tomcat執行

4.1 提前設定外部Tomcat

系統已裝有Tomcat,平常想在IDEA裡邊使用這個“外部”的Tomcat,可以先在IDEA設定:
File - Settings - Application Server,新增、新增系統已安裝的Tomcat目錄
IDEA Tomcat

4.2 提前設定外部Maven

在IDEA用Maven打包,我也用的外部Maven,IDEA設定:
IDEA MAVEN
注意:IDEA,特別是18年或者19年的新版本,Default Settings 變成了 Settings for New Projects,安裝新版的IDEA後先別急著新建工程,先在初始頁面的 Settings for New Projects 設定好系統的外部Maven,不然在IDEA裡使用的Maven總是被改回IDEA的預設Maven而不是要使用的外部Maven。不然更換編輯器IDE的時候Maven的不同會變得麻煩。

4.3 Maven打包

IDEA,Maven介面,先clean清除已生成的targets,然後package打包war。
注:打包要跳過Maven的測試的話,點選Maven介面按鍵欄的淺藍色圓圈按鍵,滑鼠懸停顯示“Skip Tests”,可見 Lifecycle下的 test 被標註了刪除線:
IDEA MAVEN
package後,在控制欄會有 “BUILD SUCCESS”,說明打包成功。

4.4 使用外部Tomcat啟動

點選Run旁邊的 Edit Configurations,點選加號“+”按鍵,別去 Templates 裡邊找
Edit
往下拉,找到 Tomcat Server 並進入,選擇Local,預設是Unnamed,提示“No artifacts marked for deployment”
在這裡插入圖片描述
修改Unnamed名稱(隨意),進入Deployment,看見Nothing to Deploy:
Deployment
點選右邊豎排加號“+”按鍵,選擇Artifact…
Artifact
選擇war,即普通打war包
war

  • 注意這個,根據需要可修改:
    context

選擇war exploded,即熱部署,修改jsp等檔案能直接顯示修改:
exploded

到這裡,外部Tomcat設定基本完成,點選OK完成,Run這裡會出現:
Tom
可以Run了。

  • 注意:要檢查專案的 Project Structure
    war的輸出路徑是否為 target:
    在這裡插入圖片描述
    於是順便檢查一下 Project的SDK版本、language level, Modules,SDKs的JDK 。

遇到問題

  • 環境:WIN7 x64
    SpringBoot 2.1.7,在IDEA新建的從 start.spring.io 生成,純淨
    系統安裝的Tomcat版本:8.0.53

用SpringBoot內部Tomcat正常啟動;
用IDEA的“外部”Tomcat無法啟動,都報錯:

failed to extract parameter names for org.apache.ibatis.mapping.resultmap...
Failed to start component [StandardEngine[Catalina].StandardHost[localhost]...
......

想看詳細的Tomcat日誌,必須去找IDEA自己的專案生成的日誌,日誌檔案在 :

C:\Users\Administrator\.IntelliJIdea2019.1\system\tomcat\Unnamed_springbootdemo\logs

看了日誌中報錯的部分,應該是連Tomcat都沒能啟動,然後才導致了接下來一堆問題,各種Bean不能註冊等等。

各種嘗試,最後發現是Tomcat版本問題!!!

啟動一個SpringBoot 2 工程,檢視到內部Tomcat版本:9.0.22
Tomcat版本
於是搜尋,帶有高版本Tomcat的SpringBoot的war,放到低版本Tomcat執行的話,
要指定Tomcat版本:

<properties>
        <!--外部Tomcat版本-->
        <tomcat.version>8.0.53</tomcat.version>
</properties>

springboot 專案部署到外部tomcat
SpringBoot應用部署到Tomcat中無法啟動問題

依舊不行!

於是搜尋 SpringBoot 2+ 的特性,發現至少要 Tomcat 8.5:
What’s New in Spring Boot 2? SpringBoot2新特性
版本
於是,直接安裝更合適的Tomcat版本,
或解除安裝原來的Tomcat後安裝更合適的Tomcat版本:
如何安裝和配置兩個不同版本的tomcat

接著IDEA裡使用 Tomcat 9.0.22 啟動,執行正常;
把war包扔到webapps目錄讓其自動部署,執行正常!

可以嘗試繼續指定外部Tomcat版本:9.0.22

<properties>
    <!--外部Tomcat版本-->
    <tomcat.version>9.0.22</tomcat.version>
</properties>

相關文章