验证响应缺少错误详细信息

mrphzbgm  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(382)

我有一个spring boot rest控制器,它接收一个带有验证字段的post主体。如果我发送了一个违反验证的主体,我会得到一个错误响应。
但在这个回答中,我缺少对错误的详细描述,这是验证失败的一部分。在后端记录的异常中,这包括在内,但我希望对客户端可见:
http响应:

{
  "timestamp": "2020-11-19T12:15:34.957+00:00",
  "status": 400,
  "error": "Bad Request",
  "message": "Validation failed for object='postBody'. Error count: 1",
  // <-- here I am missing the errors field that contains the (list of) error messages.
  "path": "/comments"
}

控制器和主体:

@RestController
@Validated
public class CommentsController {

    public void createComment(PostBody postBody) {
      //do stuff
    }
}

public class PostBody {
    private String text;

    @Size(max = 10) 
    public String getText() {
        return text;
    }
    // setter
}

后端日志中的异常包含以下错误:

2020-11-19 13:15:34 WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - 
    Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in 
    public CommentsController.createComment(PostBody): 
    [Field error in object 'postBody' on field 'text': rejected value [my very long input]; 
    codes [Size.postBody.text,Size.text,Size.java.lang.String,Size]; arguments 
    [org.springframework.context.support.DefaultMessageSourceResolvable: codes [postBody.text,text]; 
    arguments []; default message [text],10,0]; default message [size must be between 0 and 10]] ]

我是否需要配置任何其他配置以将错误详细信息输入到响应中?我希望这是开箱即用的。

5w9g7ksd

5w9g7ksd1#

我得补充一句 server.error.include-binding-errrors: always 在我的 application.yml 为了使 "errors" 错误响应中的字段:
所以我的 application.yml 现在是:

server:
  error:
    include-message: always
    include-binding-errors: always

React如下。这比我预期的要详细,但它包含了所需的信息,无需编写代码,只需配置:

{
  "timestamp": "2020-11-19T12:15:34.957+00:00",
  "status": 400,
  "errors": [
    {
      "codes": [
        "Size.postBody.text",
        "Size.text",
        "Size.java.lang.String",
        "Size"
      ],
      "arguments": [
        {
          "codes": [
            "postBody.text",
            "text"
          ],
          "arguments": null,
          "defaultMessage": "text",
          "code": "text"
        },
        10,
        0
      ],
      "defaultMessage": "size must be between 0 and 10",
      "objectName": "postBody",
      "field": "text",
      "rejectedValue": "my very long input",
      "bindingFailure": false,
      "code": "Size"
    }
  "error": "Bad Request",
  "message": "Validation failed for object='postBody'. Error count: 1", messages.
  "path": "/comments"
}

application.yml 我已经配置了这个字段 server.error.include-message: always . 否则 "message": 错误响应中的值将只是一个空字符串。
以下是github对此的讨论:https://github.com/spring-projects/spring-boot/issues/20505#issuecomment-621295137

kxkpmulp

kxkpmulp2#

我建议您使用一种方法来检查您的实体验证,这里有一个示例

private void checkIfReadyToSave(PostBody myPost) {
    Set<ConstraintViolation<Product>> violations =
        validator.validate(product, PostBodyCreation.class);
    if (!violations.isEmpty()) {
      Map<String, Object> body = new LinkedHashMap<>();
      Set<String> keys =
          violations.stream().map(ConstraintViolation::getMessage).collect(Collectors.toSet());
      body.put("errors", keys);
      throw new BeanValidationException(ErrorConstants.POST_BODY_MISSING_ERROR_MSG, body.toString());
    }
  }

这就是如何使用spring验证来进行模型验证

public class PostBody {

@NotBlank(groups = PostBodyCreation.class, message = "text.notSetted")
@Field("text")
private String text;

如何制作验证界面:

import javax.validation.groups.Default;

public interface PostBodyCreation extends Default {
}

相关问题