我参考了几篇文章,使用 Spring 为我的 rest api 项目使用@ControllerAdvice
创建全局异常处理程序。这样做的目的是在发生异常时向客户端发送正确格式的响应。在某些文章中,他们在全局异常处理程序中添加了Throwable
或Exception
。 我应该用RunTimeException
替换它,因为这个块是在运行时发生的异常?
异常处理程序代码:
@ControllerAdvice
public class GlobalExceptionHandler{
@ExceptionHandler(NoDataFoundException.class)
@ResponseStatus(code=HttpStatus.NOT_FOUND)
public ResponseEntity<ErrorResponse> handle(NoDataFoundException ex){
ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), HttpStatus.NOT_FOUND.value());
ResponseEntity<ErrorResponse> response = new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
return response;
}
..... more methods to handle custom exceptions
@ExceptionHandler(Exception.class)
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<ErrorResponse> handle(Exception ex){
ErrorResponse errorResponse = new ErrorResponse("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value());
ResponseEntity<ErrorResponse> response = new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
return response;
}
}
错误响应代码:
public class ErrorResponse {
private String message;
private int statusCode;
public ErrorResponse(String message, int statusCode) {
super();
this.message = message;
this.statusCode = statusCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatusCode() {
return statusCode;
}
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
}
引用:
- https://dzone.com/articles/exception-handling-in-spring-boot-rest-web-service
- https://github.com/in28minutes/spring-boot-examples/tree/master/spring-boot-2-rest-service-exception-handling
我应该用 RunTimeException 替换它吗,因为这个块是 运行时发生异常?
为了确保捕获引发的任何异常,并且永远不会由组件或任何异常处理程序处理,其异常类型比Exception
,您应该有一个用于Exception
的处理程序。RuntimeException
处理程序是不够的,因为检查异常也会在运行时引发,如果高级组件的方法声明指定throws Exception
或throws "any checked exception"
,则检查异常可以传播到客户端或此处将应用默认行为的容器。
例如,假设这个 rest 控制器方法声明可能会使这种情况发生:
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Foo> getOne(@PathVariable long id) throws Exception {
// ....
}
要覆盖此默认的 Spring 行为,您需要为Exception
添加一个处理程序。
当然,这并不意味着仅为Exception
声明处理程序是方法,但您可能有一些没有特定处理的例外,为此通用处理很好。
老实说,拥有异常处理程序句Exception
柄对我来说似乎有点懒惰。 由于已检查Exception
,因此您应该负责处理错误或从错误中恢复。 如果无法从错误中恢复,或者所处的情况阻止你编写允许您优雅恢复的代码,则应将其重新抛出RuntimeException
以指示问题。
当然,异常处理程序有两个用途:
- 它们使您能够定义错误响应的外观及其包含的详细信息的标准。
- 它们使您能够记录错误,以便您稍后返回并修复它。
我强烈建议将已检查Exception
重新抛出为未选中的模式,并在异常处理程序中处理这些模式。 作为故障安全捕获全部,您可以使用通用异常处理程序Exception
来捕获所有未转换的点,并记录发生的情况。
作为开发人员,您永远不应该允许Exception
在没有明确原因的情况下一直传播到顶部。