Как в Spring проверить наличие всех необходимых полей в запросе?

Как можно сделать валидацию для запроса, в котором отсутствуют обязательные поля в DTO, чтобы предоставить пользователю понятное сообщение об ошибке в случае невалидных данных? В данный момент при отсутствии обязательных полей в запросе, который передается в DTO, получаю только исключение org.springframework.http.converter.HttpMessageNotReadableException без информации о конкретных отсутствующих полях. Как решить эту проблему и обработать данный кейс?
  • 1 апреля 2024 г. 17:29
Ответы на вопрос 2
Для проверки наличия всех необходимых полей в запросе и валидации DTO с обязательными полями в Spring можно использовать встроенные механизмы валидации и аннотации. 

1. Для начала необходимо добавить зависимость Spring Boot Starter Validation в файл pom.xml:

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
```

2. Далее необходимо добавить аннотации к полям DTO, которые должны быть обязательными. Например, использовать аннотацию @NotNull:

```java
public class YourDto {
    
    @NotNull(message = "Field 'fieldName' is required")
    private String fieldName;
    
    // другие поля и методы DTO
}
```

3. Создайте обработчик исключений, который будет формировать понятное сообщение об ошибке в случае нарушения валидации:

```java
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers,
                                                                  HttpStatus status, WebRequest request) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}
```

Теперь, если приходит запрос с отсутствующими обязательными полями, будет возвращено сообщение с конкретной информацией о недостающих полях.

Также, не забывайте добавить аннотацию @Valid к методу контроллера, который принимает DTO:

```java
@PostMapping("/yourRoute")
public ResponseEntity<?> yourMethod(@Valid @RequestBody YourDto yourDto) {
    // ваша логика
}
``` 

Теперь запрос с отсутствующими обязательными полями будет обработан правильно и пользователю будет предоставлена понятная информация об ошибке.
Добрый день. 

Для валидации в спринг бут используется фреймворк - spring-boot-starter-validation
Используйте его и добавьте необходимые зависимости - NotNull, NotBlank, NotEmpty и т.д.
Далее на уровне метода контроллера, где в аргументе вы принимаете dto добавьте аннотацию @Valid или @Validated (это разные аннотации.)

Полезные ссылки
https://www.baeldung.com/spring-valid-vs-validated
https://stackoverflow.com/questions/3595160/what-d...

Ошибку будете получать - `MethodArgumentNotValidException`
Вот, даже метод для обработки исключения в @RestControllerAdvice
@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorMessage> handleValidationExceptions(
            MethodArgumentNotValidException ex,
            WebRequest request
    ) {
        var errorMessage = ErrorMessage.builder()
                .status(HttpStatus.UNPROCESSABLE_ENTITY.value())
                .message("Validating problem")
                .stackTrace(isTraceOn(request) ? getStackTrace(ex) : null)
                .build();
        if (CollectionUtils.isNotEmpty(ex.getBindingResult().getAllErrors())) {
            ex.getBindingResult().getAllErrors().forEach(
                    error -> {
                        String fieldName = error.getObjectName();
                        String errorText = error.getDefaultMessage();
                        errorMessage.addValidationError(fieldName, errorText);
                    });
        }

        return ResponseEntity.unprocessableEntity().body(errorMessage);
    }
Похожие вопросы