我正在使用 Spring Boot 开发 API。我希望 API 响应仅属于某种类型 (ResponseEntity)。当响应是另一种类型时,我想抛出一个自定义异常,以便用户获得特定的错误消息。
public class MyResponseType {
private String message;
private int statusCode;
}
@RestController
@RequestMapping("/api")
public class MyController {
// **This is OK**
@GetMapping("/example-success")
public ResponseEntity<MyResponseType> getExampleSuccess() {
MyResponseType response = new MyResponseType("This is a valid response", 200);
return new ResponseEntity.ok(response);
}
// **When invoked, this endpoint should throw an InvalidResponseTypeException.**
@GetMapping("/example-failure")
public ResponseEntity<String> getExampleFailure() {
// **We return a response of type String instead of MyResponseType.**
String response = "This is an invalid response";
return new ResponseEntity.ok(response);
}
}
// **Exception class**
public class InvalidResponseTypeException extends RuntimeException {
public InvalidResponseTypeException(String message) {
super(message);
}
}
在抛出异常之前,我认为问一些问题会很有趣,例如:我是否只需要一个自定义错误即可在特定控制器或端点中返回给用户?或者我是否必须在 API 中设置一致的错误响应并集中错误处理?
根据需要,可以添加或不添加异常抛出。所以你有两种方法:
1 - 直接返回带有错误代码的 ResponseEntity(以最少的逻辑实现快速响应):假设我们想要的只是返回一个错误,因为我们知道响应不是正确的:
@GetMapping("/example-failure")
public ResponseEntity<String> getExampleFailure() {
//Return a response of type String instead of MyResponseType.
String response = "This is an invalid response";
return new ResponseEntity<>(response, HttpStatus.NOT_ACCEPTABLE);
}
2 - 如果您确实需要异常处理,请知道异常通常是为真正的异常情况或需要在堆栈中传播的错误保留的,但也可以用于跨 API 的一致错误响应。
全局处理异常的最佳实践之一是使用@ControllerAdvice:
@GetMapping("/example-failure")
public ResponseEntity<String> getExampleFailure() {
// **Throw a new exception**
throw new InvalidResponseTypeException("Item not found")
}
...
// Here The GlobalExceptionHandler declared in the controller advice class, catches the thrown exception and responds with a consistent error
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(InvalidResponseTypeException.class)
public ResponseEntity<ErrorResponse> handleNotFoundException(InvalidResponseTypeException ex) {
ErrorResponse error = new ErrorResponse("NOT_ACCEPTABLE", ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NOT_ACCEPTABLE);
}
// You can also have in the same class other exception handlers...
}