Spring Boot中如何自定义错误JSON并获取原始请求相关信息?
自定义Spring Boot错误响应的问题
为了构建完整的最小可复现示例(MRE),只需创建一个包含web starter、Lombok的基础Spring Boot项目,并添加以下类。我使用的是Spring Boot 2.6.4,但版本不影响本问题的解决
如果你的web应用没有添加任何自定义异常逻辑,当请求一个不存在的端点时,会返回如下类似的JSON(假设请求头不包含Accept: text/html,否则会返回白标HTML页面):
{ "timestamp": "2024-02-09T05:02:23.763+00:00", "status": 404, "error": "Not Found", "path": "/bogus-path" }
这个结果不算差,但如果想要更多控制权(不是指通过server.error.include-stacktrace这类属性微调JSON)该怎么做?
为了实现自定义异常处理逻辑,我编写了一个简单的ErrorController:
import com.example.helloworldmre.data.FailureMessage; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.HttpMethod; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController public class MyErrorController implements ErrorController { @RequestMapping("/error") public FailureMessage error(HttpServletRequest request) { return new FailureMessage(HttpMethod.valueOf(request.getMethod()), request.getRequestURI()); } }
import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import org.springframework.http.HttpMethod; @Getter public class FailureMessage extends Message { @JsonProperty("request_path") private final String requestPath; private final HttpMethod method; public FailureMessage(HttpMethod method, String requestPath) { super("Could not perform the request"); this.method = method; this.requestPath = requestPath; } }
import lombok.Getter; @Getter public abstract class Message { private final String message; public Message(String message) { this.message = message; } }
我的目标是在出现错误(比如请求不存在的端点)时,返回如下格式的响应:
{ "message": "Could not perform the request", "method": "POST", "request_path": "/some-bogus-path" }
但实际返回的却是:
{ "message": "Could not perform the request", "method": "GET", "request_path": "/error" }
也就是说,我捕获到的是重定向后的路径和方法,而非原始请求的信息。
我尝试过自定义HandlerExceptionResolver:
@Component public class RestResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver { @Override protected ModelAndView doResolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { return null; // breakpoint here } }
但断点从未触发,返回的还是Spring Boot默认的JSON。
我还尝试了以下方式:
@RestControllerAdvice public class MyErrorController { @ExceptionHandler(Exception.class) public FailureMessage error(HttpServletRequest request) { return new FailureMessage(HttpMethod.valueOf(request.getMethod()), request.getRequestURI()); } }
结果依然是默认JSON。我猜测Spring Boot在收到不存在的端点请求时不会抛出异常,因此处理器无法生效。
综上,请问如何实现自定义异常处理并返回自定义JSON,同时能够:
- 获取原始请求路径
- 获取原始请求方法
- 获取具体错误信息(抛出的异常或Spring Boot映射的HTTP状态码)
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

