Technical NOTE
JSR 303 Bean Validation 내용 정리 본문
JSR 303은 Bean Validation이라는 이름으로 표준화된 자바의 검증(Validation) 메커니즘을 정의하는 사양입니다. 이 사양은 자바 객체의 속성 값이 올바른지 검증할 수 있도록 하고, 이를 통해 애플리케이션의 데이터 무결성을 유지하는 데 도움을 줍니다. JSR 303은 Java EE 및 Java SE 애플리케이션에서 모두 사용될 수 있으며, 기본적으로 어노테이션을 사용하여 검증 규칙을 설정합니다.
Bean Validation의 주요 개념과 특징
1. 어노테이션 기반 검증
Bean Validation은 어노테이션을 사용하여 자바 클래스의 필드나 메서드에 검증 규칙을 설정합니다. 각 필드에 부여된 어노테이션은 해당 값이 유효한지 검사하는 규칙을 정의하며, 이러한 어노테이션은 기본적으로 자주 사용되는 검증 요구 사항에 대한 구현을 제공합니다.
예시:
public class User {
@NotNull
@Size(min = 2, max = 30)
private String name;
@Min(18)
private int age;
@Email
private String email;
// Getter와 Setter 생략
}
위 예시에서 @NotNull
, @Size
, @Min
, @Email
과 같은 어노테이션은 각각 name
, age
, email
필드에 대한 검증을 수행합니다:
@NotNull
:null
값을 허용하지 않음.@Size(min, max)
: 문자열 길이를 제한.@Min
: 최소값을 지정.@Email
: 유효한 이메일 형식인지 확인.
2. 기본 제공 검증 어노테이션
JSR 303에서 제공하는 주요 검증 어노테이션은 다음과 같습니다.
어노테이션 | 설명 |
---|---|
@NotNull | 값이 null 이 아니어야 함. |
@Size | 문자열, 배열, 컬렉션 등의 크기(길이)가 특정 범위 내에 있어야 함. |
@Min | 숫자 값이 지정된 최소값 이상이어야 함. |
@Max | 숫자 값이 지정된 최대값 이하이어야 함. |
@Pattern | 정규 표현식(Regex)에 맞는 문자열이어야 함. |
이메일 형식이 올바른지 검증. | |
@Past | 날짜가 과거여야 함. |
@Future | 날짜가 미래여야 함. |
@Digits | 숫자의 자릿수를 제한. |
@Positive | 양수 값이어야 함. |
@Negative | 음수 값이어야 함. |
3. 검증 그룹 (Validation Group)
검증 그룹을 사용하면 상황에 따라 서로 다른 검증 규칙을 적용할 수 있습니다. 예를 들어, 회원 가입 시와 정보 수정 시 각각 다른 검증 규칙을 적용해야 할 때 그룹을 설정하여 유연한 검증이 가능합니다.
예시:
public class User {
@NotNull(groups = CreateGroup.class)
@Size(min = 2, max = 30, groups = UpdateGroup.class)
private String name;
interface CreateGroup {}
interface UpdateGroup {}
}
CreateGroup
: 생성 시 검증할 규칙.UpdateGroup
: 업데이트 시 검증할 규칙.
이를 통해 상황에 맞게 검증을 세분화할 수 있습니다.
4. 커스텀 검증 어노테이션 (Custom Constraints)
JSR 303에서는 기본 제공 어노테이션 외에도, 개발자가 직접 커스텀 검증 어노테이션을 만들 수 있습니다. 특정한 비즈니스 요구 사항에 맞는 검증이 필요할 경우, 새로운 검증 어노테이션을 정의하고 이를 활용할 수 있습니다.
커스텀 어노테이션 예시:
@Constraint(validatedBy = CustomValidator.class)
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomConstraint {
String message() default "Custom validation failed";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
커스텀 검증 로직 구현:
public class CustomValidator implements ConstraintValidator<CustomConstraint, String> {
@Override
public void initialize(CustomConstraint constraint) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// Custom validation logic here
return value != null && value.startsWith("A");
}
}
위 예시는 문자열이 "A"로 시작하는지 검증하는 커스텀 검증 어노테이션입니다.
5. 메시지 국제화 (Internationalization)
Bean Validation은 검증 실패 시 발생하는 메시지를 기본적으로 제공하지만, 커스텀 메시지나 국제화(i18n)를 지원하는 방법으로 사용할 수도 있습니다. 기본적으로 검증 어노테이션에 message
속성을 정의하여 오류 메시지를 설정할 수 있습니다.
예시:
@Size(min = 2, max = 30, message = "이름은 2자에서 30자 사이여야 합니다.")
private String name;
또한, ValidationMessages.properties 파일을 통해 각 메시지의 국제화를 관리할 수 있습니다. 파일에 다음과 같은 항목을 추가하여 특정 검증 메시지를 설정할 수 있습니다.
javax.validation.constraints.Size.message=이름의 길이는 반드시 {min}자에서 {max}자 사이여야 합니다.
6. 검증 처리 (Validation Process)
검증은 일반적으로 Validator 인터페이스를 사용하여 수동으로 처리할 수 있으며, 의존성 주입(Dependency Injection)을 통해 쉽게 사용할 수 있습니다.
검증 예시:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
User user = new User();
user.setName(null); // name에 null 값 설정
Set<ConstraintViolation<User>> violations = validator.validate(user);
for (ConstraintViolation<User> violation : violations) {
System.out.println(violation.getMessage()); // 검증 오류 메시지 출력
}
7. 스프링과 통합 (Spring Integration)
스프링 프레임워크는 JSR 303을 기본적으로 지원합니다. Spring MVC에서는 컨트롤러 메서드에서 파라미터로 받은 객체에 대해 자동으로 검증이 수행됩니다. 검증 실패 시, BindingResult를 통해 검증 오류를 처리할 수 있습니다.
예시:
@Controller
public class UserController {
@PostMapping("/users")
public String createUser(@Valid @ModelAttribute User user, BindingResult result) {
if (result.hasErrors()) {
return "form";
}
// 사용자 생성 로직
return "redirect:/users";
}
}
8. 기타 기능
- 메서드 검증: 메서드 인자 및 반환값에 대한 검증도 가능하며,
@Valid
와 검증 어노테이션을 메서드 파라미터 또는 반환값에 적용하여 사용합니다. - Java EE 및 Jakarta EE 통합: Java EE(Jakarta EE) 애플리케이션에서는 CDI(컨텍스트와 종속성 주입)와 연동하여 자동 검증을 수행할 수 있습니다.
결론
JSR 303에 정의된 Bean Validation은 자바 애플리케이션에서 객체의 데이터를 간단하고 일관되게 검증하는 방법을 제공합니다. 어노테이션 기반 검증은 코드의 가독성을 높이고 유지보수성을 개선하며, 개발자가 커스텀 검증을 정의할 수 있도록 유연성을 제공합니다. 또한 국제화 지원, 그룹 검증, 메서드 검증 등의 기능을 제공하여 다양한 요구 사항에 맞게 검증 로직을 구현할 수 있습니다.