Рубрики
Без рубрики

Списки проверки в контроллере Spring

Узнайте, как проверить список объектов в качестве параметра для контроллера Spring

Автор оригинала: baeldung.

1. введение

Проверка вводимых пользователем данных является общим требованием в любом приложении. В этом уроке мы рассмотрим способы проверки списка объектов в качестве параметра для контроллера Spring .

Мы добавим проверку на уровне контроллера, чтобы убедиться, что указанные пользователем данные удовлетворяют указанным условиям.

2. Добавление ограничений к компоненту

В нашем примере мы будем использовать простой контроллер Spring, который управляет базой данных фильмов. Мы сосредоточимся на методе, который принимает список фильмов и добавляет их в базу данных после выполнения проверки списка.

Итак, давайте начнем с добавления ограничений на фильм боб с использованием проверки javax :

public class Movie {

    private String id;

    @NotEmpty(message = "Movie name cannot be empty.")
    private String name;

    // standard setters and getters
}

3. Добавление аннотаций проверки в контроллер

Давайте посмотрим на наш контроллер. Во-первых, мы добавим @Validated аннотацию к классу контроллера :

@Validated
@RestController
@RequestMapping("/movies")
public class MovieController {

    @Autowired
    private MovieService movieService;

    //...
}

Затем давайте напишем метод контроллера, в котором мы проверим список переданных объектов Movie .

Мы добавим аннотацию @NotEmpty в наш список фильмов , чтобы убедиться, что в списке должен быть хотя бы один элемент. В то же время мы добавим аннотацию @Valid , чтобы убедиться, что сами объекты Movie являются допустимыми:

@PostMapping
public void addAll(
  @RequestBody 
  @NotEmpty(message = "Input movie list cannot be empty.")
  List<@Valid Movie> movies) {
    movieService.addAll(movies);
}

Если мы вызовем метод контроллера с пустым входом Movie list, то проверка завершится неудачей из-за аннотации @NotEmpty , и мы увидим сообщение:

Input movie list cannot be empty.

Аннотация @Valid гарантирует, что ограничения, указанные в классе Movie , будут оценены для каждого объекта в списке. Следовательно, если мы передадим Фильм с пустым именем в списке, проверка завершится ошибкой с сообщением:

Movie name cannot be empty.

4. Пользовательские Валидаторы

Мы также можем добавить пользовательский валидатор ограничений в список входных данных.

В нашем примере пользовательское ограничение будет проверять условие, что размер входного списка ограничен максимум четырьмя элементами. Давайте создадим эту пользовательскую аннотацию ограничения:

@Constraint(validatedBy = MaxSizeConstraintValidator.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MaxSizeConstraint {
    String message() default "The input list cannot contain more than 4 movies.";
    Class[] groups() default {};
    Class[] payload() default {};
}

Теперь мы создадим валидатор, который будет применять вышеуказанное ограничение:

public class MaxSizeConstraintValidator implements ConstraintValidator> {
    @Override
    public boolean isValid(List values, ConstraintValidatorContext context) {
        return values.size() <= 4;
    }
}

Наконец, мы добавим аннотацию @MaxSizeConstraint к нашему методу контроллера:

@PostMapping
public void addAll(
  @RequestBody
  @NotEmpty(message = "Input movie list cannot be empty.")
  @MaxSizeConstraint
  List<@Valid Movie> movies) {
    movieService.addAll(movies);
}

Здесь @MaxSizeConstraint проверит размер входных данных. Таким образом, если мы передадим более четырех объектов Movie во входном списке, проверка завершится неудачей.

5. Обработка исключения

Если какая-либо из проверок завершается неудачно, возникает исключение ConstraintViolationException . Теперь давайте посмотрим, как мы можем добавить компонент обработки исключений , чтобы поймать это исключение.

@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity handle(ConstraintViolationException constraintViolationException) {
    Set> violations = constraintViolationException.getConstraintViolations();
    String errorMessage = "";
    if (!violations.isEmpty()) {
        StringBuilder builder = new StringBuilder();
        violations.forEach(violation -> builder.append(" " + violation.getMessage()));
        errorMessage = builder.toString();
    } else {
        errorMessage = "ConstraintViolationException occured.";
    }
    return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
 }

6. Тестирование API

Теперь мы проверим наш контроллер с допустимыми и недопустимыми входами.

Во-первых, давайте предоставим допустимый ввод в API:

curl -v -d [{"name":"Movie1"}] -H "Content-Type: application/json" -X POST http://localhost:8080/movies

В этом сценарии мы получим ответ HTTP status 200:

...
HTTP/1.1 200
...

Затем мы проверим наш ответ API, когда мы передадим недопустимые входные данные.

Давайте попробуем пустой список:

curl -d [] -H "Content-Type: application/json" -X POST http://localhost:8080/movies

В этом сценарии мы получим ответ HTTP status 400. Это происходит потому, что входные данные не удовлетворяют ограничению @NotEmpty .

Input movie list cannot be empty.

Далее, давайте попробуем передать пять объектов Movie в списке:

curl -d [{"name":"Movie1"},{"name":"Movie2"},{"name":"Movie3"},{"name":"Movie4"},{"name":"Movie5"}] 
  -H "Content-Type: application/json" -X POST http://localhost:8080/movies

Это также приведет к ответу HTTP status 400, поскольку мы не выполняем ограничение @MaxSizeConstraint :

The input list cannot contain more than 4 movies.

7. Заключение

В этой краткой статье мы узнали, как проверить список объектов весной.

Как всегда, полный исходный код примеров находится на GitHub .