Loading...
Spring Framework Reference Documentation 7.0.2의 Java Bean Validation의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
The Spring Framework는 Java Bean Validation API를 위한 지원을 제공합니다.
Bean Validation은 Java 애플리케이션에 대해 constraint 선언과 메타데이터를 통한 공통된 validation 방식을 제공합니다. 이를 사용하려면, 런타임에 의해 강제되는 선언적 validation constraints를 도메인 모델 프로퍼티에 어노테이션으로 지정해야 합니다.
기본 제공 constraints가 있으며, 사용자 정의 custom constraints를 정의할 수도 있습니다.
다음 예시는 두 개의 프로퍼티를 가진 간단한 PersonForm 모델을 보여줍니다:
1public class PersonForm { 2 private String name; 3 private int age; 4}
1class PersonForm( 2 private val name: String, 3 private val age: Int 4)
Bean Validation을 사용하면 다음 예시와 같이 constraints를 선언할 수 있습니다:
1public class PersonForm { 2 3 @NotNull 4 @Size(max=64) 5 private String name; 6 7 @Min(0) 8 private int age; 9}
1class PersonForm( 2 @get:NotNull @get:Size(max=64) 3 private val name: String, 4 @get:Min(0) 5 private val age: Int 6)
Bean Validation validator는 선언된 constraints를 기반으로 이 클래스의 인스턴스를 검증합니다. API에 대한 일반적인 정보는 Bean Validation을 참조하십시오.
특정 constraints에 대해서는 Hibernate Validator 문서를 참조하십시오. Bean Validation provider를 Spring 빈으로 설정하는 방법을 알아보려면 계속 읽으십시오.
Spring은 Bean Validation provider를 Spring 빈으로 부트스트랩하는 것을 포함하여 Bean Validation API에 대한 완전한 지원을 제공합니다. 이를 통해 애플리케이션에서 validation이 필요한 곳 어디에서나 jakarta.validation.ValidatorFactory 또는 jakarta.validation.Validator를 주입할 수 있습니다.
다음 예시와 같이 LocalValidatorFactoryBean을 사용하여 기본 Validator를 Spring 빈으로 구성할 수 있습니다:
1import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 2 3@Configuration 4public class AppConfig { 5 6 @Bean 7 public LocalValidatorFactoryBean validator() { 8 return new LocalValidatorFactoryBean(); 9 } 10}
1<bean id="validator" 2 class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
앞의 예시에서와 같은 기본 설정은 기본 부트스트랩 메커니즘을 사용하여 bean validation이 초기화되도록 합니다. Hibernate Validator와 같은 Bean Validation provider가 클래스패스에 존재하는 것으로 예상되며 자동으로 감지됩니다.
LocalValidatorFactoryBean은 jakarta.validation.ValidatorFactory와
jakarta.validation.Validator를 모두 구현하므로, 다음 예시와 같이 Bean Validation API를 직접 사용하는 것을 선호하는 경우 후자에 대한 레퍼런스를 주입하여 validation 로직을 적용할 수 있습니다:
1import jakarta.validation.Validator; 2 3@Service 4public class MyService { 5 6 @Autowired 7 private Validator validator; 8}
1import jakarta.validation.Validator 2 3@Service 4class MyService(@Autowired private val validator: Validator)
jakarta.validation.Validator를 구현하는 것 외에도, LocalValidatorFactoryBean은 org.springframework.validation.Validator로도 동작하므로, 빈이 Spring Validation API를 필요로 하는 경우 후자에 대한 레퍼런스를 주입할 수 있습니다.
예를 들면 다음과 같습니다:
1import org.springframework.validation.Validator; 2 3@Service 4public class MyService { 5 6 @Autowired 7 private Validator validator; 8}
1import org.springframework.validation.Validator 2 3@Service 4class MyService(@Autowired private val validator: Validator)
org.springframework.validation.Validator로 사용될 때, LocalValidatorFactoryBean은 내부의 jakarta.validation.Validator를 호출한 다음 ConstraintViolation을 FieldError로 변환하고, 이를 validate 메서드에 전달된 Errors 객체에 등록합니다.
각 bean validation constraint는 두 부분으로 구성됩니다:
@Constraint 어노테이션.jakarta.validation.ConstraintValidator 인터페이스의 구현체.선언과 구현을 연결하기 위해 각 @Constraint 어노테이션은 해당하는 ConstraintValidator 구현 클래스를 참조합니다. 런타임 시에, ConstraintValidatorFactory는 도메인 모델에서 constraint 어노테이션이 발견될 때 참조된 구현을 인스턴스화합니다.
기본적으로, LocalValidatorFactoryBean은 Spring을 사용하여 ConstraintValidator 인스턴스를 생성하는 SpringConstraintValidatorFactory를 구성합니다. 이를 통해 custom ConstraintValidator들이 다른 Spring 빈과 마찬가지로 의존성 주입의 이점을 누릴 수 있습니다.
다음 예시는 custom @Constraint 선언과, 의존성 주입을 위해 Spring을 사용하는 관련 ConstraintValidator 구현을 보여줍니다:
1@Target({ElementType.METHOD, ElementType.FIELD}) 2@Retention(RetentionPolicy.RUNTIME) 3@Constraint(validatedBy=MyConstraintValidator.class) 4public @interface MyConstraint { 5}
1@Target(AnnotationTarget.FUNCTION, AnnotationTarget.FIELD) 2@Retention(AnnotationRetention.RUNTIME) 3@Constraint(validatedBy = MyConstraintValidator::class) 4annotation class MyConstraint
1import jakarta.validation.ConstraintValidator; 2 3public class MyConstraintValidator implements ConstraintValidator { 4 5 @Autowired 6 private Foo aDependency; 7 8 // ... 9}
1import jakarta.validation.ConstraintValidator 2 3class MyConstraintValidator(private val aDependency: Foo) : ConstraintValidator { 4 5 // ... 6}
앞의 예시에서 볼 수 있듯이, ConstraintValidator 구현은 다른 Spring 빈과 마찬가지로 그 의존성을 @Autowired할 수 있습니다.
Bean Validation의 메서드 validation 기능을 MethodValidationPostProcessor 빈 정의를 통해 Spring 컨텍스트에 통합할 수 있습니다:
1@Configuration 2public class ApplicationConfiguration { 3 4 @Bean 5 public static MethodValidationPostProcessor validationPostProcessor() { 6 return new MethodValidationPostProcessor(); 7 } 8}
1@Configuration 2class ApplicationConfiguration { 3 4 companion object { 5 6 @Bean 7 @JvmStatic 8 fun validationPostProcessor() = MethodValidationPostProcessor() 9 } 10}
1<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
Spring-driven 메서드 validation의 대상이 되려면, 대상 클래스는 사용될 validation 그룹을 선택적으로 선언할 수도 있는 Spring의 @Validated 어노테이션으로 표시되어야 합니다. Hibernate Validator 및 Bean Validation providers와 함께 하는 설정 세부 정보는
MethodValidationPostProcessor를 참조하십시오.
Method validation은 대상 클래스 주변의 AOP Proxies에 의존하며,<br>인터페이스의 메서드에 대해서는 JDK dynamic proxies를, 그 외에는 CGLIB proxies를 사용합니다.<br>프록시 사용에는 특정 제약이 있으며, 그 중 일부는<br>Understanding AOP Proxies에 설명되어 있습니다. 또한 항상 프록시된 클래스의 메서드와 접근자를 사용해야 하며,<br>직접적인 필드 접근은 동작하지 않는다는 점을 기억하십시오.
Spring MVC와 WebFlux는 동일한 기반 메서드 validation에 대해 AOP가 필요 없는 내장 지원을 제공합니다. 따라서 이 섹션의 나머지도 확인하고, Spring MVC의 Validation 및 Error Responses 섹션과 WebFlux의 Validation 및 Error Responses 섹션도 참조하십시오.
기본적으로, jakarta.validation.ConstraintViolationException이 jakarta.validation.Validator에 의해 반환된 ConstraintViolation의 집합과 함께 발생합니다. 대안으로, ConstraintViolation을 MessageSourceResolvable 에러로 변환한 MethodValidationException이 발생하도록 할 수 있습니다.
이를 활성화하려면 다음 플래그를 설정하십시오:
1@Configuration 2public class ApplicationConfiguration { 3 4 @Bean 5 public static MethodValidationPostProcessor validationPostProcessor() { 6 MethodValidationPostProcessor processor = new MethodValidationPostProcessor(); 7 processor.setAdaptConstraintViolations(true); 8 return processor; 9 } 10}
1@Configuration 2class ApplicationConfiguration { 3 4 companion object { 5 6 @Bean 7 @JvmStatic 8 fun validationPostProcessor() = MethodValidationPostProcessor().apply { 9 setAdaptConstraintViolations(true) 10 } 11 } 12}
1<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"> 2 <property name="adaptConstraintViolations" value="true"/> 3</bean>
MethodValidationException은 에러를 메서드 파라미터별로 그룹화하는 ParameterValidationResult 목록을 포함하며, 각 항목은 MethodParameter, 인자 값, 그리고 ConstraintViolation에서 변환된 MessageSourceResolvable 에러 목록을 노출합니다.
필드와 프로퍼티에 대해 계단식 위반이 있는 @Valid 메서드 파라미터의 경우, ParameterValidationResult는 ParameterErrors이며, org.springframework.validation.Errors를 구현하고 validation 에러를 FieldError로 노출합니다.
변환된 MessageSourceResolvable 에러는 로케일 및 언어별 리소스 번들을 가진 구성된 MessageSource를 통해 사용자에게 표시할 에러 메시지로 변환될 수 있습니다. 이 섹션에서는 예시를 통해 이를 설명합니다.
다음 클래스 선언이 주어졌다고 가정합니다:
1record Person(@Size(min = 1, max = 10) String name) { 2} 3 4@Validated 5public class MyService { 6 7 void addStudent(@Valid Person person, @Max(2) int degrees) { 8 // ... 9 } 10}
1@JvmRecord 2internal data class Person(@Size(min = 1, max = 10) val name: String) 3 4@Validated 5class MyService { 6 7 fun addStudent(person: @Valid Person?, degrees: @Max(2) Int) { 8 // ... 9 } 10}
Person.name()에 대한 ConstraintViolation은 다음과 같은 FieldError로 변환됩니다:
"Size.person.name", "Size.name", "Size.java.lang.String", "Size""name", 10, 1 (필드 이름과 constraint 속성)기본 메시지를 커스터마이징하려면, 위의 에러 코드와 메시지 인자 중 어느 것이든 사용하여 MessageSource 리소스 번들에 프로퍼티를 추가할 수 있습니다.
또한 메시지 인자 "name" 자체가 "person.name" 및 "name" 에러 코드를 가진 MessageSourceResolvable이며 역시 커스터마이징할 수 있다는 점에 유의하십시오. 예를 들면 다음과 같습니다:
Properties
1Size.person.name=Please, provide a {0} that is between {2} and {1} characters long 2person.name=username
degrees 메서드 파라미터에 대한 ConstraintViolation은 다음과 같은 MessageSourceResolvable로 변환됩니다:
"Max.myService#addStudent.degrees", "Max.degrees", "Max.int", "Max"위의 기본 메시지를 커스터마이징하려면 다음과 같은 프로퍼티를 추가할 수 있습니다:
Properties
1Max.degrees=You cannot provide more than {1} {0}
기본 LocalValidatorFactoryBean 설정은 대부분의 경우에 충분합니다. 메시지 보간부터 traversal resolution에 이르기까지 다양한 Bean Validation 구성 요소에 대한 여러 설정 옵션이 있습니다.
이러한 옵션에 대한 자세한 내용은
LocalValidatorFactoryBean
javadoc을 참조하십시오.
DataBinderDataBinder 인스턴스를 Validator로 구성할 수 있습니다. 한 번 구성되면, binder.validate()를 호출하여 Validator를 실행할 수 있습니다. 발생하는 validation Errors는 자동으로 binder의 BindingResult에 추가됩니다.
다음 예시는 대상 객체에 바인딩한 후 validation 로직을 호출하기 위해 DataBinder를 프로그래밍 방식으로 사용하는 방법을 보여줍니다:
1Foo target = new Foo(); 2DataBinder binder = new DataBinder(target); 3binder.setValidator(new FooValidator()); 4 5// bind to the target object 6binder.bind(propertyValues); 7 8// validate the target object 9binder.validate(); 10 11// get BindingResult that includes any validation errors 12BindingResult results = binder.getBindingResult();
1val target = Foo() 2val binder = DataBinder(target) 3binder.validator = FooValidator() 4 5// bind to the target object 6binder.bind(propertyValues) 7 8// validate the target object 9binder.validate() 10 11// get BindingResult that includes any validation errors 12val results = binder.bindingResult
또한 dataBinder.addValidators 및 dataBinder.replaceValidators를 통해 DataBinder를 여러 Validator 인스턴스로 구성할 수도 있습니다. 이는 DataBinder 인스턴스에 로컬로 구성된 Spring Validator와 전역적으로 구성된 bean validation을 결합할 때 유용합니다.
자세한 내용은 Spring MVC Validation Configuration을 참조하십시오.
Spring MVC 챕터의 Validation을 참조하십시오.
Configuring a Global Date and Time Format
Spring Expression Language (SpEL)