Аннотация @Valid не работает в моем приложении REST

import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

Почему, если я отправлю отрицательный возраст или пустое имя, аннотация @Valid не будет работать, и человек сохранит данные в базе данных?

На сервер отправляется следующий JSON.

{
    "name": "",
    "age": -30
}

@Entity Человек:

@Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "name")
    @NotEmpty(message = "Name mustn't be empty!")
    @Size(min = 2, max = 20, message = "Name must be between 2 and 20 characters long!")
    private String name;

    @Column(name = "age")
    @Min(value = 1, message = "Age must be greater than 0!")
    private int age;

Метод контроллера:


@PostMapping
    public ResponseEntity<HttpStatus> create(@RequestBody @Valid Person person, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            StringBuilder errorMsg = new StringBuilder();

            List<FieldError> errors = bindingResult.getFieldErrors();
            for (FieldError error : errors) {
                errorMsg.append(error.getField()).append(" - ").append(error.getDefaultMessage()).append(";");
            }

            throw new PersonNotCreatedException(errorMsg.toString());
        }

        personService.savePerson(person);

        return ResponseEntity.ok(HttpStatus.OK);
    }

org.springframework.validation.BeanPropertyBindingResult: 0 ошибок

Вы не показали полный класс контроллера, но я полагаю, вы пропустили для него аннотацию @Validated.

Alex 20.05.2024 21:14

Позвольте мне угадать только jakarta.validation-api в пути к классам вместо использования spring-boot-starter-validation?

M. Deinum 21.05.2024 14:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
58
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Рассмотрите возможность использования аннотации @Validated в верхней части контроллера вместе с зависимостью maven для проверки, если вы еще не используете стартовую веб-зависимость:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Ответ принят как подходящий

Вы уверены, что у вас есть зависимость?

Градл:

implementation 'org.springframework.boot:spring-boot-starter-validation'

Мейвен:

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

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

@PostMapping
    public ResponseEntity<HttpStatus> create(@RequestBody @Valid PersonCreateRequest requestBody, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            StringBuilder errorMsg = new StringBuilder();

            List<FieldError> errors = bindingResult.getFieldErrors();
            for (FieldError error : errors) {
                errorMsg.append(error.getField()).append(" - ").append(error.getDefaultMessage()).append(";");
            }

            throw new PersonNotCreatedException(errorMsg.toString());
        }

        personService.savePerson(requestBody); // use Mapper in service

        return ResponseEntity.ok(HttpStatus.OK);
    }

Спасибо. Похоже, я слишком устал, чтобы это заметить. Спасибо за совет, я ценю это.

elenwen 20.05.2024 23:21

пожалуйста, реализуйте правильную зависимость в вашем файле pom.xml

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

для проекта Springboot Maven

Другие вопросы по теме