#java #spring-boot #validation
#java #весенняя загрузка #проверка
Вопрос:
У меня есть контроллер Spring Boot Rest, который получает текст сообщения с проверенным полем. Если я отправляю тело, которое нарушает проверку, я получаю ответ об ошибке.
Но в этом ответе мне не хватает подробного описания ошибок, какая часть проверки не выполняется. В зарегистрированном исключении в серверной части это включено, но я бы хотел, чтобы оно было видно для клиента:
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]] ]
Нужно ли мне настраивать что-либо дополнительное, чтобы получить сведения об ошибках в ответе? Я бы ожидал, что это будет включено из коробки.
Ответ №1:
Я должен добавить server.error.include-binding-errors: always
в свой application.yml
, чтобы включить "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
Ответ №2:
Я рекомендую вам использовать метод для проверки проверки вашей сущности, есть пример
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.Defau<
public interface PostBodyCreation extends Default {
}
Комментарии:
1. Я использую сгенерированный OpenAPI объект RequestBody, поэтому, я думаю, было бы сложно добавить пользовательский валидатор в поле.
2. Вы можете добавить его в свою модель, которая будет отображать объект запроса open API