본문 바로가기
IT개발/Spring5

[Spring5] 커맨드 객체 검증(Validate(), @Valid, Bean Validation)

by Thompson 2024. 11. 24.
728x90

웹 애플리케이션에서 사용자 입력을 받을 때, 올바른 데이터인지 확인하는 "검증(validation)"은 매우 중요합니다. Spring에서는 커맨드 객체(command object)를 활용해 검증 로직을 쉽게 작성할 수 있습니다. 


1. 컨트롤러에서 커맨드 객체 검증 (Validate() 메서드 사용)

커맨드 객체란 사용자가 폼에 입력한 데이터를 매핑하는 객체입니다. Spring에서는 Validator 인터페이스를 사용해 검증 로직을 명시적으로 작성할 수 있습니다.

주요 메서드

  • rejectValue(field, errorCode): 특정 필드에 오류 추가.
  • reject(errorCode): 객체 전체에 오류 추가.

예시 코드

// 1. Validator 구현
public class UserValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return User.class.isAssignableFrom(clazz); // User 객체만 검증
    }

    @Override
    public void validate(Object target, Errors errors) {
        User user = (User) target;

        // 이름 필드 검증
        if (user.getName() == null || user.getName().isEmpty()) {
            errors.rejectValue("name", "name.empty", "이름은 필수 항목입니다.");
        }

        // 나이 필드 검증
        if (user.getAge() < 18) {
            errors.rejectValue("age", "age.invalid", "18세 이상만 가입 가능합니다.");
        }
    }
}

 

컨트롤러에서 Validator를 호출하여 검증을 수행합니다.

@Controller
public class UserController {
    private final UserValidator userValidator = new UserValidator();

    @PostMapping("/register")
    public String register(@ModelAttribute User user, BindingResult result) {
        userValidator.validate(user, result); // 검증 실행

        if (result.hasErrors()) {
            return "registerForm"; // 에러 발생 시 폼으로 돌아감
        }

        return "success";
    }
}

2. @Valid를 사용한 컨트롤러 단위 검증

Spring은 Bean Validation(JSR-380) 기반의 어노테이션인 @Valid를 사용하여 간편하게 검증할 수 있습니다. 이를 사용하면 Validator 구현 없이 어노테이션만으로 검증이 가능하며, 컨트롤러 메서드 단위로 적용됩니다.

 

커맨드 객체 정의

public class User {
    @NotBlank(message = "이름은 필수 항목입니다.") // null, 공백 방지
    private String name;

    @Min(value = 18, message = "18세 이상만 가입 가능합니다.") // 최소값 제한
    private int age;

    // Getter/Setter 생략
}

컨트롤러 메서드에 @Valid 사용

@Controller
public class UserController {
    @PostMapping("/register")
    public String register(@Valid @ModelAttribute User user, BindingResult result) {
        if (result.hasErrors()) {
            return "registerForm";
        }
        return "success";
    }
}

 

글로벌 컨트롤러 단위

공통적인 검증이 필요할 경우, 글로벌 범위에서 @InitBinder를 사용해 Validator를 등록할 수 있습니다.

@ControllerAdvice
public class GlobalValidatorConfig {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.addValidators(new UserValidator()); // 공통 Validator 등록
    }
}
 

3. Bean Validation 사용(@Valid)

Spring은 표준 Java Bean Validation을 지원합니다. 커맨드 객체에 어노테이션을 추가하여 검증 로직을 작성하며 다음과 같은 어노테이션을 사용합니다.

  • @NotBlank : 빈 문자열 방지
  • @Min / @Max : 숫자의 최소값/최대값
  • @Size : 문자열 또는 컬렉션의 크기 제한
  • @Email : 이메일 형식 검증
public class User {
    @NotBlank(message = "이름은 필수 항목입니다.")
    private String name;

    @Min(value = 18, message = "18세 이상만 가입 가능합니다.")
    private int age;

    @Email(message = "유효한 이메일 주소를 입력하세요.")
    private String email;
}

 

컨트롤러에서 다음과 같이 정의

@PostMapping("/register")
public String register(@Valid @ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "registerForm";
    }
    return "success";
}

Spring은 Validator 인터페이스와 @Valid를 사용해 유연하고 강력한 데이터 검증을 지원합니다. 상황에 따라 명시적인 Validator를 구현하거나, 간단하게 어노테이션 기반의 Bean Validation을 사용할 수 있습니다.