SpringBoot Restful API 自定义错误响应格式

通常我们会通过spring的异常处理器来自定义响应格式,即通过@RestControllerAdvice来实现,但是如果只是为了自定义一个返回格式的话有更好的选择,那就是自定义ErrorController,所有未被处理的异常都会被它处理,@RestControllerAdvice也被视为异常处理,即被@RestControllerAdvice处理的异常将不会到达这里,直接上代码,以Kotlin为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@RestController
@RequestMapping("/error")
class GlobalErrorController : ErrorController {

@Autowired
lateinit var errorAttributes: ErrorAttributes

@RequestMapping
fun error(request: HttpServletRequest): ResponseEntity<ErrorResponse> {
val ex: Throwable? = errorAttributes.getError(ServletWebRequest(request))
val status = getStatus(request)
return ResponseEntity.status(status)
.body(ErrorResponse(status = status.name, message = ex?.localizedMessage ?: ""))
}

private fun getStatus(request: HttpServletRequest): HttpStatus {
val statusCode = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)

if (statusCode !is Int) {
return HttpStatus.INTERNAL_SERVER_ERROR
}

return try {
HttpStatus.valueOf(statusCode)
} catch (e: Exception) {
HttpStatus.INTERNAL_SERVER_ERROR
}
}
}
  • 这里注入了一个ErrorAttributes类型的bean,它包含了请求上下文的错误信息,通过getError方法可以获取到异常类

  • 匹配到路由/error的方法的返回值会作为响应发送到客户端,当然这个路由是可以自定义的

需要注意的是,如果配置spring.mvc.throw-exception-if-no-handler-foundfalse,由于404不会引发异常,所以通过getError方法获取到的异常将会为null。同时@RestControllerAdvice将不起作用,因为它只会捕获异常,这也是其相比ErrorController的劣势

PS:异常处理的顺序为 主动捕获异常->@RestControllerAdvice->ErrorController->Servlet容器,如Tomcat。被处理过的异常将不会到达下一级

SpringBoot Restful API 自定义错误响应格式

https://jktu.cc/SpringBoot-Restful-API-自定义错误响应格式/

作者

udp_bbr

发布于

2021-09-05

更新于

2022-09-08

许可协议