Spring Boot 默认异常处理
当我们用 spring boot 开发接口是,当遇到异常时返回的数据格式是如下形式的
{
"timestamp": "2024-07-06T02:48:55.791+00:00",
"status": 404,
"error": "Not Found",
"path": "/test"
}
{
"timestamp": "2024-07-06T02:53:09.108+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/test"
}
这样的数据格式可能和我们接口的数据格式不相符,如果我们想让我们的服务返回统一的数据格式,就需要进行自定义异常处理。
Spring Boot 异常处理实现
当我们向 spring boot 应用发送请求,处理出错时(比如:404,或者对应的接口服务处理逻辑异常)都会将请求转发到 “/error”上,“/error” 的默认请求是由BasicErrorController 处理的核心代码如下:
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
return new ResponseEntity<>(status);
}
Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
return new ResponseEntity<>(body, status);
}
处理完后的响应数据格式也就是上面我们提到的默认数据格式。
自定义异常返回数据格式
在 ErrorMvcAutoConfiguration 配置类中由如下代码
@Bean
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes,
ObjectProvider<ErrorViewResolver> errorViewResolvers) {
return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
errorViewResolvers.orderedStream().collect(Collectors.toList()));
}
通过上述代码可知,只要我们自定义一个 ErrorController 类型的 bean ,BasicErrorController 就不会生效了,所以我们自定义一个 CustomerErrorController 并实现 ErrorController 代码如下
@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class CustomerErrorController implements ErrorController {
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = new HashMap<>();
body.put("code", "1001");
body.put("message", "请求不存在");
return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
}
}
再次访问不存在的请求,返回如下数据格式
{
"code": "1001",
"message": "请求不存在"
}
自此,自定义异常返回数据格式功能大功告成。