【问题标题】:Handle Custom Validations and Exceptions in REST with SpringBoot使用 SpringBoot 处理 REST 中的自定义验证和异常
【发布时间】:2019-07-10 12:20:27
【问题描述】:

Sample Project Attached Here

我正在关注这篇文章API Error Handling(也请建议是否有更好的方法来做到这一点)在我的 Spring Boot Rest 服务中以通用方式处理异常和验证。 (我是 spring 和 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"}

感谢任何帮助。

【问题讨论】:

  • 你好 Saravana,有什么错误吗?另外,共享可疑代码而不是整个项目
  • 您能否分享您在哪个控制器端点上提出请求
  • 我在 PersonController 中做。由于 @Valid 甚至在我返回之前它在我的 RestCustomExceptionHandler 中得到验证,但返回的响应没有 subErrors 部分。你能看看我在 github 上的代码吗

标签: java spring rest spring-boot validation


【解决方案1】:

您需要在 APICustomError 中添加 getter 和 setter 以正确序列化您的对象。您还需要内部类 APIValidationError 的公共构造函数和 getter/setter。我建议你使用 Lombok。

之后你会看到类似这样的错误...

{
   "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"
}

【讨论】:

  • 响应格式非常混乱。本文toptal.com/java/spring-boot-rest-api-error-handling 中的代码产生了以下输出,这是我所期望的。 {"apierror":{"status":"BAD_REQUEST","timestamp":"10-07-2019 06:41:32","message":"验证错误","subErrors":[{"object": "bird","field":"mass","re​​jectedValue":1.0E7,"message":"必须小于等于 104000"}]}}
  • 我错过了您在 APICustomError 中使用内部类,之前的响应不是您的错误处理程序。现在是。
  • 太棒了!添加 getter 和 setter 之后。它按预期工作。非常感谢。只是一个小问题?这种方法是否更适合处理验证?
  • 据我所知,这是正确处理错误的好方法。在这种情况下,您仅将其用于格式化,但这是一种非常常见的做法。问候。
【解决方案2】:

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

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);
}

【讨论】:

    猜你喜欢
    • 2014-02-21
    • 2013-07-02
    • 2017-11-28
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    相关资源
    最近更新 更多