在开发 Web 应用时,有效的错误处理和响应是提升用户体验和系统健壮性的关键。Spring Boot 3.2 引入了对 ProblemDetail 的更好支持,使得错误处理更加标准化和便捷。本文将通过实战演示,带你深入了解如何在 Spring Boot 3.2 中使用 ProblemDetail 实现错误处理的标准化。
一、ProblemDetail 简介
ProblemDetail 是 RFC 7807 定义的一种标准格式,用于在 HTTP API 中表示错误信息。它以 JSON 格式返回错误的详细信息,包括状态码、错误标题、详细描述等。Spring Boot 3.2 提供了对 ProblemDetail 的内置支持,使得我们可以轻松地在应用中实现标准化的错误响应。
二、引入依赖
在 Spring Boot 3.2 中,ProblemDetail 的支持已经内置,无需额外引入依赖。如果你使用的是 Spring Boot 3.2 以下版本,建议升级到最新版本以获得更好的支持。
三、创建自定义异常
在实际应用中,我们通常会定义一些自定义异常来表示特定的错误情况。以下是一个示例:
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
public class CustomException extends ResponseStatusException {
public CustomException(HttpStatus status, String reason) {
super(status, reason);
}
}
四、全局异常处理
//本人正在项目中正在用的代码
@ControllerAdvice
@Slf4j
public class ExceptionCatchController {
@ExceptionHandler({Exception.class})
@ResponseBody
public Result exception(HttpServletRequest request, Exception ex) {
log.error("ExceptionHandler error,url:{},meg:{}", request.getRequestURI(), ex.getMessage(), ex);
Result result = Result.getInternalErrorResult(request.getRequestURI()
+ " 网页异常: " + ex.getMessage());
if (ex instanceof HttpRequestMethodNotSupportedException) {
result.setCode(405);
}
if (ex instanceof HttpMessageNotReadableException) {
result.setCode(400);
}
if (ex instanceof PermissionsException) {
result.setCode(403);
}
if (ex instanceof BaseException) {
result.setCode(500);
result.setMessage(ex.getMessage());
}
return result;
}
}
下面是demo: 使用 @ControllerAdvice
注解创建一个全局异常处理器,可以捕获并处理各种异常。
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.server.ResponseStatusException;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<ProblemDetail> handleResponseStatusException(ResponseStatusException ex) {
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(ex.getStatus(), ex.getReason());
return ResponseEntity.status(ex.getStatus()).body(problemDetail);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ProblemDetail> handleException(Exception ex) {
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(problemDetail);
}
}
五、使用 ProblemDetail 返回错误信息
在控制器中,我们可以直接返回 ProblemDetail 对象,Spring Boot 会自动将其转换为标准的 JSON 格式。
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@GetMapping("/test")
public ResponseEntity<ProblemDetail> test() {
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "This is a test error");
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(problemDetail);
}
}
六、测试与验证
启动应用后,访问 /test
接口,可以看到返回的错误信息符合 ProblemDetail 的标准格式:
{
"type": "https://httpstatuses.org/400",
"title": "Bad Request",
"status": 400,
"detail": "This is a test error"
}
七、总结
通过使用SpringBoot3.2的ProblemDetail,我们可以轻松实现错误处理的标准化,提升应用的用户体验和系统健壮性。希望本文的内容对你有所帮助,让你在实际项目中能够更好地处理错误。