0

我正在验证传入的 POST 请求,该请求将在验证请求数据后创建一个数据库实体。我正在尝试在单个请求中收集多个错误,并按照 JSON API 规范作为错误响应进行响应:

https://jsonapi.org/examples/#error-objects-multiple-errors

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "status": "403",
      "source": { "pointer": "/data/attributes/secretPowers" },
      "detail": "Editing secret powers is not authorized on Sundays."
    },
    {
      "status": "422",
      "source": { "pointer": "/data/attributes/volume" },
      "detail": "Volume does not, in fact, go to 11."
    },
    {
      "status": "500",
      "source": { "pointer": "/data/attributes/reputation" },
      "title": "The backend responded with an error",
      "detail": "Reputation service not responding after three requests."
    }
  ]
}

是否可以通过@ControllerAdvice. 当全局异常处理被启用@ControllerAdvice并抛出异常时,不会捕获下一个异常。

4

1 回答 1

2

不直接,不。不确定您的业务案例/逻辑是什么,因此我不知道您如何在服务层处理这些异常,但总的来说,如果您想在 @ExceptionHanlder 中传递多个错误 - 您可以创建一个自定义 POJO:

public class MyError {
    private String status;
    private String source;
    private String title;
    private String detail;

    getters/setters...
}

然后创建一个自定义 RuntimeException 接受这些 POJO 的列表:

public class MyRuntimeException extends RuntimeException {
    private final List<MyError> errors;

    public MyRuntimeException(List<MyError> errors) {
        super();
        this.errors = errors;
    }

    public List<MyError> getErrors() {
        return errors;
    }
}

在您的服务层中,您可以创建这些 POJO 的列表,然后将其包装在您的异常中并抛出它。然后在 @ControllerAdvice 中,您只需捕获您的异常并调用访问器方法来迭代您的 POJO 列表以构造您想要的有效负载。就像是:

@ExceptionHandler (MyRuntimeException.class)
@ResponseStatus (BAD_REQUEST)
@ResponseBody
public Map<String, Object> handleMyRuntimeException(MyRuntimeException e) {
    return singletonMap("errors", e.getErrors());
}
于 2020-11-09T14:33:31.853 回答