如何为Spring Boot 404响应添加errorId字段(2018年5月版本)
解决方案:让自定义异常的errorId出现在Spring Boot错误响应中
好问题!在你使用的2018年5月版Spring Boot(对应2.0.x系列)里,默认的错误响应结构只会提取几个固定属性,不会自动包含自定义异常的额外字段。不过有两种简单的方式可以实现你想要的效果:
方法一:自定义ErrorAttributes(推荐,全局生效)
Spring Boot通过ErrorAttributes接口生成错误响应内容,我们可以继承默认的DefaultErrorAttributes,重写方法来添加自定义字段:
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.stereotype.Component; import org.springframework.web.context.request.WebRequest; import java.util.Map; @Component public class CustomErrorAttributes extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { // 获取默认的错误属性集合 Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace); // 获取当前抛出的异常对象 Throwable error = getError(webRequest); // 判断异常类型,如果是自定义的NotFoundException,就添加errorId字段 if (error instanceof NotFoundException) { NotFoundException notFoundEx = (NotFoundException) error; errorAttributes.put("errorId", notFoundEx.getErrorId()); // 顺便把message改成你想要的格式(去掉前缀的errorId) String originalMsg = (String) errorAttributes.get("message"); if (originalMsg != null && originalMsg.contains(",")) { errorAttributes.put("message", originalMsg.split(",", 2)[1]); } } return errorAttributes; } }
这个类会被Spring自动扫描并替换默认的ErrorAttributes,所有错误响应都会遵循这个逻辑,不仅限于NotFoundException。
方法二:用@ControllerAdvice全局处理特定异常
如果你只想针对NotFoundException做定制化处理,可以创建全局异常处理器,直接返回自定义的响应体:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(NotFoundException.class) public ResponseEntity<Map<String, Object>> handleNotFound(NotFoundException ex, WebRequest request) { Map<String, Object> responseBody = new HashMap<>(); // 构建你期望的响应字段 responseBody.put("timestamp", System.currentTimeMillis()); responseBody.put("status", HttpStatus.NOT_FOUND.value()); responseBody.put("error", HttpStatus.NOT_FOUND.getReasonPhrase()); responseBody.put("exception", ex.getClass().getName()); // 拆分原始message,只保留错误描述部分 responseBody.put("message", ex.getMessage().split(",", 2)[1]); responseBody.put("path", request.getDescription(false).replace("uri=", "")); responseBody.put("errorId", ex.getErrorId()); return new ResponseEntity<>(responseBody, HttpStatus.NOT_FOUND); } }
这种方式更灵活,你可以完全控制响应的结构和内容,甚至可以返回自定义的DTO对象而不是Map。
为什么默认没有errorId?
Spring Boot的默认错误处理逻辑只会提取异常的几个核心属性(timestamp、status、error、exception、message、path),不会自动遍历异常的所有getter方法并添加到响应中,所以需要我们手动扩展。
内容的提问来源于stack exchange,提问作者Vering
相关产品推荐
相关产品推荐

