nyximos.log

@Valid 본문

Programming/Spring

@Valid

nyximos 2024. 11. 7. 22:01

@Valid

  • Java Bean Validation (JSR-380) 제공
    • 빈 검증기를 이용해 객체의 제약 조건을 검증한다.
  • 검증 그룹을 지원 ❌
  • MethodArgumentNotValidException 발생
  • @NotNull, @Size, @Email, @Min, @Max, @Pattern(regexp), @NotBlank 등의 유효성 검증 어노테이션을 사용한다.
  • 객체 필드에 위 어노테이션을 쓰고 컨트롤러 메소드에 @Valid를 붙여주자

 

@Valid 동작 원리

  1. Java Bean Validation API: @Valid는 Java Bean Validation API의 일부분입니다. 이 API는 표준화된 방법으로 객체의 유효성을 검증하는 메커니즘을 제공합니다.
  2. 유효성 검사 트리거: @Valid 어노테이션이 적용된 필드나 메서드 파라미터는 유효성 검사를 트리거합니다. 이 때, 해당 객체 내에 있는 유효성 검사 어노테이션들(@NotNull, @Size, @Email 등)이 실행됩니다.
  3. Bean Validation Provider: Java Bean Validation API는 구체적인 구현체(예: Hibernate Validator)와 함께 작동합니다. 이 구현체가 실제 유효성 검사를 수행합니다. Spring에서는 보통 Hibernate Validator가 사용됩니다.
  4. 검증 과정:
    • 단일 객체 검증: @Valid가 적용된 객체의 모든 필드에 대해 유효성 검사가 수행됩니다.
    • 중첩된 객체 검증: 만약 @Valid가 중첩된 객체에 적용되었다면, 해당 객체의 필드에 대해서도 재귀적으로 유효성 검사가 수행됩니다.
    • 컬렉션/배열 검증: 컬렉션이나 배열에 @Valid가 적용되면, 각 요소에 대해 유효성 검사가 수행됩니다.
  5. 검증 실패 처리: 유효성 검사가 실패하면, ConstraintViolationException 또는 Spring MVC에서는 MethodArgumentNotValidException이 발생합니다. 이 예외는 컨트롤러의 글로벌 예외 처리기에서 처리될 수 있습니다.
  6. 전역 예외 처리: 유효성 검사에 실패하면 발생한 예외를 잡아, 사용자에게 적절한 오류 메시지를 반환하거나 다른 로직을 수행할 수 있습니다. Spring에서는 @ControllerAdvice와 @ExceptionHandler를 사용해 이를 처리합니다.

 

사용

의존성 추가해주자!

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation'

 

@Getter
@Setter
public class SignUpRequestModel {

    @NotNull(message = "email은 null이 될 수 없습니다.")
    @Email(message = "유효한 이메일 주소를 입력해 주세요.")
    @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.")
    private String email;

    @NotNull(message = "password는 null이 될 수 없습니다.")
    private String password;

}

 

@Valid를 붙여주면 유효성 검증을 해준다 !

@RestController
@RequiredArgsConstructor
@RequestMapping("/apis/users")
public class UserController {

    private final UserService userService;

    @PostMapping
    public ResultResponse signUp(@Valid @RequestBody SignUpRequestModel signUpRequestModel) {
        userService.signUp(signUpRequestModel);
        return new ResultResponse<>();
    }

}

 

전역 예외 처리

ExceptionHandler를 생성해서 이런식으로 예외를 처리하였다.

@ExceptionHandler

  • 특정 예외 발생 시 해당 메서드가 호출한다.
  • 아래 코드에서는 MethodArgumentNotValidException 예외를 처리한다.

ex.getBindingResult().getAllErrors().forEach(x -> sb.append(x).append("\n"));

  • MethodArgumentNotValidException에서 BindingResult를 가져와서 모든 오류를 리스트로 반환한다.
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultResponse handleValidationExceptions(MethodArgumentNotValidException ex) {
    Map<String, String> errors = new HashMap<>();
    StringBuilder sb = new StringBuilder();
    ex.getBindingResult().getAllErrors().forEach(x -> sb.append(x).append("\n"));
    return new ResultResponse<>(HttpStatus.BAD_REQUEST, sb.toString().trim());
}

 

 

 

 

Reference

 

[Spring] @Valid와 @Validated를 이용한 유효성 검증의 동작 원리 및 사용법 예시 - (1/2)

Spring으로 개발을 하다 보면 DTO 또는 객체를 검증해야 하는 경우가 있습니다. 이를 별도의 검증 클래스로 만들어 사용할 수 있지만 간단한 검증의 경우에는 JSR 표준을 이용해 간결하게 처리할 수

mangkyu.tistory.com