1. 소개

사용자 입력의 유효성을 검사하는 것은 모든 응용 프로그램의 일반적인 요구 사항입니다. 이 예제에서는 객체 List 을 Spring 컨트롤러에 대한 매개 변수로 검증하는 방법을 살펴 보겠습니다 .

사용자 지정 데이터가 지정된 조건을 충족하는지 확인하기 위해 컨트롤러 계층에 유효성 검사를 추가합니다.

2. 빈에 제약 추가

이 예에서는 영화 데이터베이스를 관리하는 간단한 Spring 컨트롤러를 사용합니다. 영화 List을 받아들이고 List에서 유효성 검사를 수행 한 후 데이터베이스에 추가하는 방법에 초점을 맞출 것입니다.

따라서 javax 유효성 검사를 사용하여 Movie에 제약 조건을 추가하여 시작하겠습니다 .

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 객체 List의 유효성을 검사 할 컨트롤러 메서드를 작성해 보겠습니다 .

우리는 것이다 추가 @NotEmpty의 영화의 우리의 List에 어노테이션을 List에서 적어도 하나 개의 요소가 될 것을 확인 할 수 있습니다. 동시에 Movie 객체 자체가 유효한지 확인하기 위해 @Valid 어노테이션을 추가 합니다.

@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 어노테이션은 있는지에 지정된 제약 있는지 확인합니다 영화 클래스 List에있는 각 개체에 대해 평가됩니다. 따라서 List에서 이름이 비어 있는 Movie전달하면 다음 메시지와 함께 유효성 검사가 실패합니다.

Movie name cannot be empty.

4. 맞춤 유효성 검사기

입력 List에 사용자 지정 제약 조건 유효성 검사기추가 할 수도 있습니다 .

예를 들어 사용자 지정 제약 조건은 입력 List 크기가 최대 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<? extends Payload>[] payload() default {};
}

이제 위의 제약을 적용 할 유효성 검사기를 만들 것입니다.

public class MaxSizeConstraintValidator implements ConstraintValidator<MaxSizeConstraint, List<Movie>> {
    @Override
    public boolean isValid(List<Movie> 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 는 입력 크기를 확인합니다. 따라서 입력 List에 4 개 이상의 Movie 객체를 전달 하면 유효성 검사가 실패합니다.

5. 예외 처리

유효성 검사 중 하나라도 실패하면 ConstraintViolationException 이 throw됩니다. 이제이 예외 를 포착하기 위해 예외 처리 구성 요소를 추가하는 방법을 살펴 보겠습니다 .

@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity handle(ConstraintViolationException constraintViolationException) {
    Set<ConstraintViolation<?>> 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 상태 200 응답을 받게됩니다.

...
HTTP/1.1 200
...

다음으로 잘못된 입력을 전달할 때 API 응답을 확인합니다.

빈 List을 시도해 보겠습니다.

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

이 시나리오에서는 HTTP 상태 400 응답을받습니다. 입력이 @NotEmpty 제약 조건을 충족하지 않기 때문 입니다.

Input movie list cannot be empty.

다음으로 List에서 5 개의 Movie 객체를 전달해 보겠습니다 .

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

또한 @MaxSizeConstraint 제약 조건이 실패하기 때문에 HTTP 상태 400 응답이 발생합니다 .

The input list cannot contain more than 4 movies.

7. 결론

이 빠른 기사에서는 Spring에서 객체 List의 유효성을 검사하는 방법을 배웠습니다.

항상 그렇듯이 예제의 전체 소스 코드는 GitHub에 있습니다 .