spring boot 全局异常处理捕获资源未找到异常(404)的核心在于区分“控制器内部抛出的业务异常”与“框架底层拦截的 http 状态码”。对于控制器中手动抛出的 `resourcenotfoundexception`,使用 @controlleradvice 配合 @exceptionhandler 即可直接拦截;而对于访问不存在的 url 触发的默认 404,由于它由 spring mvc 的 dispatcherservlet 在请求映射阶段直接返回,通常不会触发标准的异常处理链,需要通过自定义 errorcontroller 或配置 simplemappingexceptionresolver 来统一接管响应格式。

@ControllerAdvice 如何拦截自定义的业务异常
当应用逻辑中发现资源不存在时,主动抛出继承自 RuntimeException 的自定义异常,全局异常处理器能精准捕获并转换为 JSON 响应。通过定义一个专门的异常类如 ResourceNotFoundException,并在服务层抛出,控制器层的 @ExceptionHandler 方法就能接收该实例,进而构建包含错误码和消息的标准响应体。这种方式适用于所有已知业务场景下的资源缺失判断。

package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
// 1. 定义自定义异常
class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
// 2. 全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<map object>> handleResourceNotFound(ResourceNotFoundException ex) {
Map<string object> body = new HashMap();
body.put("error", "NOT_FOUND");
body.put("message", ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(body);
}
}
// 3. 示例控制器
@RestController
@RequestMapping("/api")
class DemoController {
@GetMapping("/items/{id}")
public String getItem(@PathVariable Long id) {
if (id == null || id <h2>如何处理 Spring MVC 默认的 404 路径未匹配异常</h2>
<p>当用户访问一个完全不在 <code>@RequestMapping</code> 映射范围内的 URL 时,Spring MVC 会抛出 <code>NoHandlerFoundException</code> 或直接返回 404 状态码而不经过常规的异常处理器链。为了统一这些底层异常的响应格式,需要实现 <code>ErrorController</code> 接口并重写 <code>getErrorPath</code> 方法,或者在 <code>application.properties</code> 中启用 <code>spring.mvc.throw-exception-if-no-handler-found=true</code> 并将 <code>spring.web.resources.add-mappings=false</code>,从而将 404 转化为可被 <code>@ExceptionHandler</code> 捕获的异常对象。推荐做法是实现 <code>ErrorController</code> 以接管所有错误路径的响应。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6631" title="Spring Boot Actuator Analyzer"><img
src="https://img.php.cn/upload/skill/000/000/081/179103250068943.jpg" alt="Spring Boot Actuator Analyzer" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill6631" title="Spring Boot Actuator Analyzer" class="overflowclass">Spring Boot Actuator Analyzer</a>
<p class="overflowclass">分析Spring Boot Actuator端点的安全性、健康检查、指标暴露及生产配置——审计信息、健康状态和自定义端点。</p>
</div>
<a rel="nofollow" href="/xiazai/skill6631" title="Spring Boot Actuator Analyzer" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p><img src="https://img.php.cn/upload/article/001/242/473/179454390743544.png?x-oss-process=image/resize,p_40" alt="Spring Boot 全局异常处理怎么捕获资源未找到异常"></p>
<pre class="brush:php;toolbar:false;">package com.example.demo;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@Controller
public class CustomErrorController implements ErrorController {
private static final String ERROR_PATH = "/error";
@RequestMapping(ERROR_PATH)
public ResponseEntity<map object>> error(HttpServletRequest request) {
Map<string object> body = new HashMap();
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
String errorMessage = (String) request.getAttribute("javax.servlet.error.message");
if (statusCode != null && statusCode == HttpStatus.NOT_FOUND.value()) {
body.put("error", "NOT_FOUND");
body.put("message", "The requested resource is not available.");
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(body);
}
// 其他错误处理...
body.put("error", "UNKNOWN");
body.put("message", "An unexpected error occurred.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(body);
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}</string></map>
当 NoHandlerFoundException 未被启用时默认行为是什么
如果未在配置文件中显式开启 throw-exception-if-no-handler-found,Spring Boot 默认会将无法匹配的请求视为静态资源查找失败,直接由内置的 Tomcat 容器返回标准的 HTML 404 页面,此时 @ControllerAdvice 和自定义 ErrorController 均无法介入,因为请求从未进入 Spring MVC 的 DispatcherServlet 核心流程进行异常分发。这意味着开发者必须明确配置属性才能将这种“静默”的 404 转化为可编程处理的异常事件,否则 API 客户端将收到非预期的 HTML 内容而非 JSON 结构。










