使用SpringBoot处理REST中的自定义验证和异常

时间:2019-07-10 12:20:27

标签: java spring rest spring-boot validation

Sample Project Attached Here

我正在关注本文API Error Handling(也请建议是否有更好的方法)来在我的Spring Boot Rest服务中以通用方式处理异常和验证。 (我是春季和休息的新手,所以我要根据自己的需要阅读不同的文章)

有关要求的基本概念:

(需要验证POST请求并以结构化方式将验证错误发送给客户端。可能存在多个验证错误)

只要我从客户端收到POST请求,就需要验证RequestBody。因此,我在参数上添加了@Valid,并在要验证的属性上添加了@NotNull。收到POST请求后,spring正在验证请求并抛出MethodArgumentNotValidException,这很好,因为我缺少一些必填字段。 我在@ControllerAdvice的一个普通地方处理它。点击适当的方法handleMethodArgumentNotValid(...)之后,我将构建我的自定义错误响应APICustomError,我从上述文章中遵循。

当我有多个验证错误时,我可以循环所有错误并将其添加到列表中,并使用我的自定义错误构造ResponseEntity。 但是返回的ResponseEntity没有添加的验证错误。

我理解了这篇文章,并在我的项目中实现了该文章,但实际上并没有得到我所缺少的内容。

以下是文章中所述的输出,我期望的是:

{
   "apierror":{
      "status":"BAD_REQUEST",
      "timestamp":"10-07-2019 12:53:24",
      "message":"Validation error",
      "subErrors":[
         {
            "object":"person",
            "field":"id",
            "rejectedValue":null,
            "message":"ID cannot be null"
         },
         {
            "object":"person",
            "field":"name",
            "rejectedValue":null,
            "message":"name cannot be null"
         }
      ]
   }
}

但是下面是我得到的。我根本看不到subErrors部分。

{"message":"Validation Error","debugMessage":null,"detail":null,"httpStatus":"BAD_REQUEST","timestamp":"2019-07-10T17:08:00.52"}

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您需要在APICustomError中添加getter和setter才能正确序列化您的对象。您还需要公共构造函数和内部类APIValidationError的getter / setter方法。我建议您使用龙目岛。

之后,您将看到错误,如下所示……

{
   "message": "Validation Error",
   "debugMessage": null,
   "subErrors": [
       {
           "object": "personDTO",
           "field": "id",
           "rejectedValue": null,
           "validationErrorMessage": "ID cannot be null."
       }
   ],
   "detail": null,
   "httpStatus": "BAD_REQUEST",
   "timestamp": "2019-07-10T10:25:44.1705441"
}

答案 1 :(得分:0)

试试这个 在您的控制器建议中

protected ResponseEntity<Object> handleMethodArgumentNotValid(
                MethodArgumentNotValidException ex,
                HttpHeaders headers, 
                HttpStatus status, WebRequest request) {
    Response response = new Response();
    List<FieldError> errors = ex.getBindingResult().getFieldErrors();
    List<SubError> errors = new ArrayList<>();

    for (FieldError e : errors) {
        SubError error = new SubError():
        error.setMessage(String.format(MESSAGE_FORMAT, egetCOde));
        errors.add(error);
    }
    response.setSubError(errors);
    return new ResponseEntity(response, HttpStatus.BAD_REQUEST);
}