StackTraces
Spring Boot已驗證

Spring Boot 報 Whitelabel Error Page

@debug_master32 天前更新閱讀 6 min00

白頁不是 bug,是「沒匹配到 Controller」的症狀。Spring MVC 找不到能處理請求的方法,就把請求丟給 /error,預設的 BasicErrorController 接手後渲染出這段白頁。排查別盯著 /error,該回去查包結構、註解和映射路徑。

Issue & Env(案發現場與環境)

  • 現象:瀏覽器訪問某個接口或頁面,返回一段空白錯誤頁,而不是預期內容。
  • 環境:Spring Boot 2.x / 3.x,spring-boot-starter-web,內嵌 Tomcat。預設開啟 Whitelabel 錯誤頁。

StackTrace(堆疊日誌)

瀏覽器裡顯示的是 HTML,不是例外堆疊:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

There was an unexpected error (type=Not Found, status=404).

也可能是 500 或 405:

There was an unexpected error (type=Internal Server Error, status=500).

關鍵在 type=Not Found, status=404:它說明你的請求本身返回了 404,白頁只是這個錯誤的預設渲染。

打開 DEBUG 日誌後,服務端會打印完整的轉發鏈:

2026-09-03 10:15:32.108 DEBUG 12345 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : GET "/hello", parameters={}
2026-09-03 10:15:32.110 DEBUG 12345 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 404 NOT_FOUND
2026-09-03 10:15:32.111 DEBUG 12345 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : ERROR "/error", parameters={}
2026-09-03 10:15:32.115 DEBUG 12345 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 200 OK

如果開啟了 server.error.include-stacktrace=always,控制台能看到被吞掉的例外:

org.springframework.web.servlet.NoHandlerFoundException: No handler found for GET /hello
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1086)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:152)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:462)

Reproduce(復現程式碼)

最常見的一種:主類在 com.example 包,Controller 卻放到這個包之外。

// 主类:com.example.Application
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
// 放错位置:com.controller.HelloController,不在 com.example 包下
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "ok";
    }
}

啟動後訪問 http://localhost:8080/hello,返回的就是 Whitelabel 404 頁。

Root Cause(根因分析)

主類上的 @SpringBootApplication 隱含了 @ComponentScan,掃描範圍預設是主類所在包及其子包。Controller 一旦放到這個包之外,就不會被註冊成 bean,@GetMapping 的映射也就沒進路由表。

請求進來後,DispatcherServlet 用 HandlerMapping 去找能處理這個 URL 的處理器。找不到,就轉發到錯誤路徑 /error。Spring Boot 自動註冊的 BasicErrorController 正好映射在 /error 上,接手後按 Accept 頭返回 HTML,就是那個 Whitelabel 頁面。所以報錯文案裡那句「no explicit mapping for /error」會誤導人——真正沒被映射的是你請求的那個 URL,不是 /error。

除了包結構,還有幾類常見原因:

  1. 用了 @Component 而不是 @Controller / @RestController,類成了 bean,但方法沒暴露成 HTTP 映射。
  2. URL 或 HTTP 方法寫錯,比如接口是 POST,你偏用 GET 訪問。
  3. 用原生 @WebServlet 寫 Servlet,Spring Boot 預設不掃它,除非加 @ServletComponentScan。

The Fix(解決方案)

先定位是哪種。開 DEBUG 日誌能在啟動時看到所有註冊的映射,一眼判斷你的接口在不在:

logging.level.org.springframework.web=DEBUG

包結構放錯,就把 Controller 挪回主類包下,或在主類顯式擴大掃描範圍:

@SpringBootApplication(scanBasePackages = "com.example")
public class Application { }

註解用錯就改回 @RestController;方法錯了就改 @GetMapping / @PostMapping;用了 @WebServlet 就加 @ServletComponentScan 或直接改寫 Spring MVC Controller。

想徹底告別白頁,加一個全局例外處理或自定義錯誤視圖。只想關掉它,設 server.error.whitelabel.enabled=false,但那樣只會露出 Tomcat 預設錯誤頁,不如自己接管 /error。

References(參考來源)

最後更新於 2026-09-09

這篇幫到你了嗎?

剛解決了一個棘手的報錯?花兩分鐘記錄下來,幫助下一個遇到同樣問題的開發者。

貢獻一條解法