記SpringBoot升級Tomcat引發的兩類典型問題及解決方案
在SpringBoot項目維護過程中,版本升級是常見操作,但往往會引發一些兼容性問題。本文記錄了將SpringBoot內置Tomcat從8.5.51升級到9.0.75後遇到的兩個典型問題:URL包含雙斜槓//導致404、DELETE請求報HttpRequestMethodNotSupportedException,並給出對應的解決方案和原理分析。
一、URL包含//導致404問題
問題現象
Tomcat版本升級至9.0.75後,前端點擊菜單出現404錯誤,排查發現請求URL中存在連續的雙斜槓(如/api//user/list),將Tomcat回退到8.5.51後問題消失。
問題原因
Tomcat 9.x對URL的規範化處理邏輯相比8.x更嚴格:
- Tomcat 8.5.51會自動將URL中的連續斜槓
//合併為單斜槓/,因此即使URL拼寫不規範也能正常訪問; - Tomcat 9.0.75默認不再自動合併連續斜槓,導致包含
//的URL無法匹配後端接口,觸發404錯誤。
解決方案
方案1:統一規範前端菜單URL配置(推薦)
從根源上解決問題,檢查並修正所有菜單、前端請求的URL配置,將所有連續的//替換為單斜槓/。
示例:
- 錯誤URL:
/system//menu - 修正後:
/system/menu
方案2:配置Tomcat允許合併連續斜槓(應急方案)
若暫時無法批量修正URL,可通過配置Tomcat參數恢復8.x的URL處理邏輯:
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TomcatConfig {
@Bean
public ServletWebServerFactory servletWebServerFactory() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addConnectorCustomizers((Connector connector) -> {
// 開啓URL規範化,合併連續斜槓
connector.setNormalizeUri(true);
// Tomcat 9.x新增參數,允許路徑中的連續斜槓
connector.setAttribute("allowBackSlash", true);
connector.setAttribute("normalizePath", true);
});
return tomcat;
}
}
二、DELETE請求報HttpRequestMethodNotSupportedException異常
問題現象
前端發起DELETE請求時,後端拋出如下異常:
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
問題原因
瀏覽器原生只支持GET和POST請求,前端通常通過form表單+隱藏參數的方式模擬DELETE/PUT請求。SpringBoot中處理該場景的HiddenHttpMethodFilter過濾器默認是關閉的(尤其是高版本SpringBoot),導致POST請求無法被轉換為DELETE請求,進而觸發請求方法不支持的異常。
解決方案
方案1:開啓HiddenHttpMethodFilter(配置文件方式)
在application.properties或application.yml中添加配置:
# 開啓HiddenHttpMethodFilter過濾器,支持POST模擬DELETE/PUT請求
spring.mvc.hiddenmethod.filter.enabled=true
spring:
mvc:
hiddenmethod:
filter:
enabled: true
方案2:手動註冊HiddenHttpMethodFilter(代碼方式)
若配置文件方式不生效,可手動註冊過濾器:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.HiddenHttpMethodFilter;
@Configuration
public class WebConfig {
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new HiddenHttpMethodFilter();
}
}
前端配合示例
前端需在POST表單中添加_method=DELETE隱藏參數:
<form action="/api/user/1" method="post">
<input type="hidden" name="_method" value="DELETE">
<button type="submit">刪除用户</button>
</form>
補充説明
HiddenHttpMethodFilter僅處理Content-Type為application/x-www-form-urlencoded的POST請求;- 若前端使用Axios等AJAX工具,可直接設置
method: 'DELETE',無需依賴該過濾器; - 過濾器優先級:若項目中有自定義過濾器,需保證
HiddenHttpMethodFilter執行順序靠前。
三、總結
- Tomcat 9.x對URL規範化更嚴格,需統一規範URL拼寫(避免
//),或通過配置恢復8.x的URL處理邏輯; - SpringBoot中模擬DELETE/PUT請求需開啓
HiddenHttpMethodFilter,核心配置為spring.mvc.hiddenmethod.filter.enabled=true; - 版本升級前建議先做小範圍驗證,重點關注基礎組件(如Tomcat)的行為變更,提前規避兼容性問題。
四、擴展建議
- 建立URL規範檢查機制:在前端工程中添加ESLint規則,禁止URL中出現連續斜槓;
- 統一請求方式:新項目建議優先使用RESTful API+AJAX(Axios/Fetch),減少表單模擬DELETE/PUT的場景;
- 版本兼容:升級依賴前查閲官方變更日誌,重點關注核心組件(Tomcat、Spring框架)的行為變更點。