Spring Boot中404需配置spring.mvc.throw-exception-if-no-handler-found=true和spring.web.resources.add-mappings=false后,再用@ControllerAdvice捕获NoHandlerFoundException;500可直接通过@ExceptionHandler处理运行时异常。

Spring Boot 中 404 和 500 错误的全局捕获方式不同,核心在于:500 类异常(如 RuntimeException、数据库异常等)可直接用 @ControllerAdvice + @ExceptionHandler 捕获;而 404(即 NoHandlerFoundException)默认不走该机制,需额外配置才能被捕获并统一处理。
下面分两类说明具体做法:
一、500 类异常:用 @ControllerAdvice 自然捕获
这类异常是 Controller 层抛出的未处理运行时异常,Spring MVC 默认会进入全局异常处理器。
只需定义一个带 @ControllerAdvice 的类,并用 @ExceptionHandler 注解方法:
- 捕获所有异常:
@ExceptionHandler(Exception.class) - 捕获特定异常:
@ExceptionHandler(NullPointerException.class) - 方法返回 @ResponseBody 对象(如 Map、自定义 Result),或 ResponseEntity 控制状态码
- 建议加上 @Order(Ordered.HIGHEST_PRECEDENCE) 确保优先级最高
示例返回 JSON:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<string object> handle500(Exception e) {
Map<string object> result = new HashMap();
result.put("code", 500);
result.put("msg", "服务器内部错误");
return result;
}
}</string></string>
二、404 异常:需开启配置才可捕获
默认情况下,404 不是“抛出的异常”,而是 DispatcherServlet 找不到匹配 Handler 时直接返回的状态码,不会触发 @ExceptionHandler。
要让它也能被全局捕获,必须做两件事:
- 在 application.properties 或 application.yml 中启用“找不到处理器时抛出异常”:
application.properties:
spring.mvc.throw-exception-if-no-handler-found=true spring.web.resources.add-mappings=false
application.yml:
spring:
mvc:
throw-exception-if-no-handler-found: true
web:
resources:
add-mappings: false
- 然后在 @ControllerAdvice 类中添加专门处理 NoHandlerFoundException 的方法:
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseBody
public Map<string object> handle404(NoHandlerFoundException e) {
Map<string object> result = new HashMap();
result.put("code", 404);
result.put("msg", "请求地址不存在");
return result;
}</string></string>
⚠️ 注意:spring.web.resources.add-mappings=false 是为了防止静态资源映射干扰 404 判定(尤其在禁用默认静态路径时更稳妥)。
三、补充:前后端分离场景下的友好响应
当客户端(如 axios、fetch)请求时 Accept 头为 application/json,Spring Boot 的 BasicErrorController 会自动返回 JSON 格式错误体。但该默认行为不可定制。
所以更推荐的方式是:
- 关闭默认错误控制器(可选):
server.error.whitelabel.enabled=false - 用上面的 @ControllerAdvice 完全覆盖 404/500,统一返回结构化 JSON
- 配合自定义异常类(如 ServiceException)和通用返回体(如 CommonResult),提升可读性和扩展性
四、自定义 404/500 页面(非 JSON 场景)
如果项目使用 Thymeleaf 或其他模板引擎,且面向浏览器用户,可直接放页面文件:
- Thymeleaf:在
src/main/resources/templates/error/下建404.html和500.html - 纯静态页(无模板引擎):放在
src/main/resources/static/error/目录下 - 页面名必须严格为
404.html、500.html,Spring Boot 会自动匹配
这种方式无需写 Java 代码,适合管理后台、运营系统等仍以页面为主的应用。











