springboot項目打成war包丟到tomcat webapps下能啓動卻訪問不了相關的接口

  • 背景
    1. springboot 項目,在idea中正常運行(內置tomcat),外部(前端)訪問接口正常;
        確認已添加依賴
    <!--打包形式-->
    <packaging>war</packaging>
    ...
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-tomcat</artifactId>
    	<scope>provided</scope>
    </dependency>
    <!--		該依賴的作用是:在項目打包時,剔除springboot內置tomcat。-->
    <!--		如果沒有該步驟,打成的war包內,會有關於內置tomcat的多餘的jar包,但是並不影響項目最終的部署與運行。-->
    2. 利用 maven 打包成 war:mvn clean install  --->> xx.war
    3. 機器下載的tomcat 8.5xx 壓縮包,解壓安裝。
        (1) 編輯 tomcat 配置文件設置 訪問端口爲 項目配置文件中配置的端口號(保持訪問端口不變)
        (2) 將打包好的 war 包複製到 tomcat/webapps 目錄下
        (3) 啓動 tomcat:bin/startup.xx
        (4) 啓動成功,訪問接口-->> 404
  • 解決方法
    1. 參考 
        項目在intellij idea裏配置tomcat可以啓動訪問, 打成war包丟到tomcat webapps下能啓動卻訪問不了相關的接口
        這個問題是因爲idea會默認將項目以ROOT爲目錄的文件
        而丟到tomcat的webapps下面則是解壓成你項目名稱爲目錄的文件,和ROOT是同級的
        可以有以下幾種解決方案
        一:將你的war名稱改成作爲ROOT.war
        二:在tomcat的server.xml文件的Host標籤內配置<Context path="/" docBase="你項目的地址" reloadable="true"/>
        三:用tomcat發佈時,將前端請求的路徑加上你的項目名稱
    2. tomcat 版本問題
       換成 tomcat 9.0xx,同樣的步驟,訪問成功
       tomcat 8.5xx,訪問路徑設置無效,訪問時不能加項目名稱,查看tomcat文件,發現項目war包被解壓成兩份,ROOT下一份
    3. springboot項目內置tomcat問題,以及tomcat版本的支持,重點(可以看後續)
        考慮到springboot web啓動器包含內置tomcat,改用外部 tomcat
        (1) 依賴,(雖然已經添加依賴打包是剔除springboot的tomcat)
    <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>
    <!-- 添加servlet-api依賴 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

      (2) 修改啓動類,並重寫初始化方法:讓啓動類繼承SpringBootServletInitializer,並覆蓋configure()方法

    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;
    
    @SpringBootApplication
    public class Application extends SpringBootServletInitializer {
    	public static void main(String[] args) {
    		SpringApplication.run(Application.class, args);
    	}
    
    	@Override
    	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        // 注意這裏要指向原先用main方法執行的Application啓動類
    		return application.sources(Application.class);
    	}
    }

    (3) idea中指定tomcat容器,配置訪問端口和路徑,啓動--成功
    (4) 打包,或者將(3)中啓動後生成的war包(target下),複製到tomcat目錄下,記得設置tomcat的訪問端口號
    (5) 啓動tomcat 成功,可訪問

  • 原因
        (1) Tomcat 9.0設計用於運行在Java se 8及以後的版本 -- 項目用的是jdk1.8
        (2) 不同 tomcat 版本針對不同版本的 jdk 項目,需要進行特殊的配置(修改配置文件)
        (3) springboot內置tomcat的處理,在低版本的tomcat中未進行適應性處理
  • 總結
    本人對照了很多配置項,除了端口基本都屬於默認配置,對網上較多的所謂解決方法的配置修改來看,都沒有實際效果,而且啓動均是正常,如果是訪問路徑設置的問題,總有一個訪問路徑是可以訪問到的纔對,不管是在tomcat中指定項目路徑,還是在訪問路徑上加上項目名或者不加或者加上兩個項目名都訪問不到,最終,也是找到原因 tomcat 版本和springboot版本的不適配,最好還是直接換成 tomcat 9.0,完全沒得什麼問題。
     
  • 對 tomcat 8x 8.5x 和 9.0x 的各種發行可能沒有詳細瞭解,希望對遇到同樣問題的你有幫助,如有不對或者疑問的地方,請大方指出,相互學習
     
  • 後續
    springboot 指定 外部 tomcat 運行
    Error:Cannot build artifact 'tube (1):war exploded' because it is included i
    1. 將 tomcat 整合進 idea,指定 tomcat 8.5xx 運行,正常運行,接口可訪問
    2. 拿到 上面 打包好的 xx.war 複製到 tomcat 8.5xx 的 webapps 目錄下,啓動,接口可訪問!!!且此處設置路徑有效
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章