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

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法