1. 程式人生 > >springboot 在idea多模組下 子模組的web專案用內建tomcat啟動訪問jsp報404

springboot 在idea多模組下 子模組的web專案用內建tomcat啟動訪問jsp報404

問題描述:最近公司換spring boot 做微服務開發。多個微服務按模組匯入匯入到idea。之前是單獨的專案匯入。能正常啟動和正常訪問。換到idea的專案--模組結構之後。發現用內建tomcat啟動web專案無法訪問到jsp頁面了。(ps:打成war包到外面tomcat啟動是沒有問題。只是不服,發現這個奇葩的問題沒找到原因心中不爽。)

問題分析:無法訪問jsp,很自然想到:一是路徑有沒有對映對?二是檔案不存在。檢查一遍之後發現對映沒有問題,檔案也存在。這就比較奇葩了。唯有看一下springboot在啟動的時候如何定義web root的路徑。跟一下springboot的tomcat啟動包的原始碼:

/**
 * Returns the absolute document root when it points to a valid directory, logging a
 * warning and returning {@code null} otherwise.
 * @return the valid document root
 */
protected final File getValidDocumentRoot() {
   File file = getDocumentRoot();
   // If document root not explicitly set see if we are running from a war archive
file = file != null ? file : getWarFileDocumentRoot(); // If not a war archive maybe it is an exploded war file = file != null ? file : getExplodedWarFileDocumentRoot(); // Or maybe there is a document root in a well-known location file = file != null ? file : getCommonDocumentRoot(); if
(file == null && this.logger.isDebugEnabled()) { this.logger .debug("None of the document roots " + Arrays.asList(COMMON_DOC_ROOTS) + " point to a directory and will be ignored."); } else if (this.logger.isDebugEnabled()) { this.logger.debug("Document root: " + file); } return file; }

發現有三種取路徑方式。war包 getWarFileDocumentRoot,匯出包 getExplodedWarFileDocumentRoot,和文件 getCommonDocumentRoot。內建tomcat啟動應該屬於第三種。跟進去第三種發現:

private static final String[] COMMON_DOC_ROOTS = { "src/main/webapp", "public",
      "static" };
private File getCommonDocumentRoot() {
   for (String commonDocRoot : COMMON_DOC_ROOTS) {
      File root = new File(commonDocRoot);
      if (root != null && root.exists() && root.isDirectory()) {
         return root.getAbsoluteFile();
      }
   }
   return null;
}

寫死從上面配置的3個目錄去取doc路徑。

看到這裡問題就明瞭。關鍵是 

File root = new File(commonDocRoot);
if (root != null && root.exists() && root.isDirectory()) {
   return root.getAbsoluteFile();
}

File root = new File("src/main/webapp") 的是 這個相對路徑的字首是取哪裡的。

百度得知 取的是

System.getProperty("user.dir")

相當於 File root = new File(System.getProperty("user.dir")+"src/main/webapp");

然後 debug 列印一下 System.getProperty("user.dir") 發現 是定位到了 專案那層 而不是模組那層

解決方法:既然發現了問題,解決就簡單。這裡採用的是直接在啟動項裡面增加配置引數,將"user.dir" 定位到模組裡面。

問題解決。

最後:因為對tomcat的啟動順序不瞭解。跟這個過程的時候走了不少彎路。採用了最笨的方法,在後面層層倒推一直找到上面設定doc路徑的方法。如果熟悉原理,直接從開始就定位到那個方法就很快能解決了。所以記錄下來。避免自己或有遇到同樣問題的人少走彎路。