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



我有一个Spring Boot Rest控制器,它接收一个带有验证字段的post body。如果我发送了一个违反验证的正文,我会得到一个错误响应。

但在回复中,我遗漏了对错误的详细描述,验证的哪一部分失败了。在后端记录的异常中,这是包括在内的,但我希望对客户端可见:

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

控制器和PostBody:

@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]] ]

我是否需要配置其他内容以将错误详细信息输入响应?我希望这个能开箱即用。

我必须在application.yml中添加server.error.include-binding-errors: always,才能启用错误响应中的"errors"字段:

所以我的application.yml现在是:

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

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

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

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

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

这就是如何使用弹簧验证进行模型验证

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

最新更新