Bean 유효성 검증

Bean 유효성 검증 API는 프리젠테이션, 비즈니스 및 데이터 액세스를 포함하여 응용프로그램의 모든 레이어에서 JavaBeans의 유효성을 검증하는 표준 메커니즘으로 Java™ Enterprise Edition 6플랫폼과 함께 도입됩니다.

빈 검증 스팩 (Bean Validation specification) 이전에, JavaBeans는 각각의 층에서 확인되었다. 각 계층에서 유효성 검증을 다시 구현하지 않기 위해 개발자는 유효성 검증을 해당 클래스에 직접 번들하거나 유효성 검증 코드를 복사하여 너무 어수선했습니다. 애플리케이션의 모든 계층에 공통된 구현을 하나로 통일하면 개발자의 작업이 단순화되고 시간이 절약됩니다.

Bean 유효성 검증 스펙은 데이터 무결성을 위해 JavaBeans의 유효성을 검증하는 데 사용되는 메타데이터 모델과 API를 정의한다. 메타데이터 소스는 XML 유효성 검증 디스크립터를 사용하여 대체 및 확장이 가능하도록 정의되는 제한조건 어노테이션입니다. API 세트는 모든 애플리케이션 계층이 동일한 유효성 검증 제한조건 세트를 사용하도록 하는 편리한 프로그래밍 모델을 제공합니다. 유효성 검증 제한조건은 어노테이션이 있는 필드, 메소드, 유형 값을 검사하여 정의된 제한조건을 준수하도록 합니다.

제한조건은 빌드되거나 사용자 정의될 수 있습니다. javax.validation.constraints 패키지에는 몇몇 어노테이션이 내장되어 있습니다. 이 어노테이션을 사용하여 일반 제한조건 정의를 정의하고 제한조건을 구성합니다. 기본 제공 제한조건 목록은 Bean 유효성 검증 기본 제공 제한조건 정보를 참조하십시오. Bean 유효성 검증 메타데이터 모델 및 API에 대한 자세한 정보는 JSR 349 Bean 유효성 검증 스펙 문서를 참조하십시오.

다음 예제는 기본 제공 제한조건 어노테이션으로 데코레이션된 단순 EJB (Enterprise JavaBeans) 클래스이다.

public class Home  {
   @Size(Max=20)
    String builder; 
    @NotNull @Size(Max=20)
    String address;

    public String getAddress() {
         return address;
    }

    public String getBuilder() {
         return address;
    }
    public String setAddress(String newAddress) {
         return address = newAddress;
    }

    public String setBuilder(String newBuilder) {
         return builder = newBuilder; 
    }
}

빌더 및 주소의 @Size 어노테이션은 지정된 문자열 값이 20자를 넘지 않도록 합니다. 주소의 @NotNull 어노테이션은 널이 될 수 없음을 표시합니다. Home 오브젝트의 유효성이 검증되면 빌더와 주소 값이 @Size 어노테이션에 정의된 유효성 검증기 클래스로 전달됩니다. 주소 값도 @NotNull 유효성 검증기 클래스로 전달됩니다. 유효성 검증기 클래스는 적절한 제한조건 값 검사를 처리하고 임의의 제한조건 유효성 검증이 실패하면 ConstraintViolation 오브젝트가 작성되고 Home 오브젝트 유효성 검증 호출자로 설정되어 리턴됩니다.

유효성 검증 API

javax.validation 패키지에는 JavaBeans의 유효성을 프로그램적으로 검증하는 방법을 설명하는 빈 유효성 검증 API가 포함되어 있다.

ConstraintViolation은 단일 제한조건 실패를 설명하는 클래스입니다. ConstraintViolation 클래스 세트는 오브젝트 유효성 검증을 위해 리턴됩니다. 제한조건 위반은 위반을 설명하는 육안으로 읽을 수 있는 메시지로 표시됩니다.

유효성 검증 중에 실패하면 ValidationException이 처리됩니다.

유효성 검증기 인터페이스는 기본 유효성 검증 API이고 유효성 검증기 인스턴스는 자바 오브젝트 필드, 메소드 및 유형의 값을 유효성 검증할 수 있는 오브젝트입니다. 부트스트랩 API는 Validator 인터페이스 작성에 사용되는 ValidatorFactory 액세스를 가져오기 위해 사용되는 메커니즘입니다. 제품에 배치된 애플리케이션의 경우 부트스트랩은 자동으로 완료됩니다. 애플리케이션은 두 가지 방법으로 유효성 검증기 또는 ValidatorFactory를 가져올 수 있습니다. 하나는 인젝션으로 예를 들어, @Resource 어노테이션 사용이고 다른 방법은 java 검색입니다.

다음 예는 인젝션을 사용하여 ValidatorFactory 및 Validator를 확보합니다.
@Resource ValidatorFactory _validatorFactory;
@Resource Validator _validator;    
주의: @Resource 를 사용하여 유효성 검증기 또는 ValidatorFactory를 가져오는 경우, authenticationType및 shareable 요소를 지정하지 않아야 합니다.
다음 예는 JNDI를 사용하여 ValidatorFactory 및 Validator를 확보합니다.
ValidatorFactory validatorFactory = (ValidatorFactory)context.lookup("java:comp/ValidatorFactory");
Validator validator = (Validator)context.lookup("java:comp/Validator");

제한조건 메타데이터 요청 API

메타데이터 API 지원 도구 제공자는 다른 프레임워크, 라이브러리 및 Java Platform, Enterprise Edition 기술과의 통합을 제공합니다. 오브젝트 제한조건의 메타데이터 저장소는 지정된 클래스의 Validator 인터페이스를 통해 액세스합니다.

XML 배치 디스크립터

어노테이션에 제한조건을 선언하는 것 이외에도 XML을 사용하여 제한조건을 선언하는 지원도 가능합니다.

유효성 검증 XML 설명은 두 개의 xml 파일 종류로 구성됩니다. META-INF/validation.xml 파일은 모듈에 대한 Bean 유효성 검증 구성을 설명합니다. 다른 XML 파일 유형은 제한조건 선언을 설명하고 어노테이션 선언 메소드와 근접하게 일치합니다. 기본적으로 어노테이션을 통해 표시되는 모든 제한조건 선언은 XML로 설명되는 클래스에 대해 무시됩니다. Bean에서 ignore-annotation="false" 설정을 사용하여 어노테이션 및 XML 제한조건 선언 모두를 사용하도록 강제로 유효성 검증할 수 있습니다. 제품은 validation.xml 파일을 포함하는 배치되는 애플리케이션 모듈 및 XML 파일에 정의되는 제한조건이 XML 디스크립터를 포함하는 모듈에만 고유한 Validator 인터페이스를 작성하여 다른 모듈 validation.xml 및 제한조건 파일에서 격리되도록 합니다.

고급 Bean 유효성 검증 개념

Bean 유효성 검증 API는 기본 제공 제한조건 및 사용자 정의 제한조건을 선언하도록 하는 인터페이스 세트를 제공합니다. 이는 제한조건 어노테이션을 작성하고 Bean 유형, 필드 또는 특성의 어노테이션을 선언하여 수행됩니다. 제한조건 작성은 다른 제한조건 정의에 제한조건을 선언해서도 수행합니다.

다음 예는 주석 문자열 필드가 널이 아니도록 정의되는 CommentChecker 제한조건 작성을 보여줍니다. 주석 텍스트는 대괄호 안에 입력해야 합니다(예: [text]).

package com.my.company;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.validation.Constraint;
import javax.validation.Payload;
    
@Documented
@Constraint(validatedBy = CommentValidator.class)
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
public @interface CommentChecker {
       String message() default "The comment is not valid.";
       Class<?>[] groups() default {};
       Class<? extends Payload>[] payload() default {};
     	…} 
다음 예는 @CommentChecker 어노테이션을 사용하여 요소의 유효성 검증을 처리하는 제한조건 유효성 검증기를 보여줍니다. 제한조건 유효성 검증기는 Bean 유효성 검증 API에서 제공하는 ConstraintValidator 인터페이스를 구현합니다.
package com.my.company;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class CommentValidator implements ConstraintValidator<CommentChecker, String> {
    public void initialize(CommentChecker arg0) {       
    }
    public boolean isValid(String comment, ConstraintValidatorContext context) {
        if (comment == null) {
            // Null comment is not allowed, fail the constraint. 
            return false;
        }
        if (!comment.contains("[") && !comment.contains("]")) {
            // Can't find any open or close brackets, fail the constraint
            return false;
        }
        // Ignore leading and trailing spaces
        String trimmedComment = comment.trim();
        return // validate '[' prefix condition
               trimmedComment.charAt(0) == '[' && 
               // validate ']' suffix condition
               trimmedComment.charAt(trimmedComment.length()!-1) == ']';
    }
}
@CommentChecker 정의 후에 주석 문자열 필드가 CommentValidator isValid() 구현을 기반으로 유효한 주석인지 확인하는 데 사용할 수 있습니다. 다음 예는 @CommentChecker 제한조건 사용을 보여줍니다. myChecker Bean 유효성이 검증되면 주석 문자열은 정의된 제한조건이 충족되는지 확인하기 위해 CommentValidator 클래스로 유효성 검증됩니다.
package com.my.company;
public myChecker {  

    @CommentChecker
    String comment = null; 
    ...
}

제품은 기본 Bean 유효성 검증 제공자를 제공하지만 애플리케이션에서 대체 제공자를 사용하고자 할 수 있습니다. 유효성 검증 팩토리를 작성하기 위해 javax.validation.Validation.byProvider() 메소드를 호출하여 프로그래밍 방식으로 대체 제공자를 선택할 수 있습니다. 또는 validation.xml 파일에 <default-provider/> 요소를 지정하여 대체 제공자를 선언적으로 선택할 수 있습니다. 대체 제공자 클래스가 기본 제공자와 충돌하지 않도록 하려면 서버 또는 애플리케이션 클래스 로더 순서를 Classes loaded with local class loader first (parent last)값으로 설정하십시오. 이를 설정하는 방법에 대한 추가 정보는 클래스 로드 문서를 참조하십시오.

Bean 유효성 검증 스펙은 둘 이상의 validation.xml 파일이 클래스 경로에 있는 경우 ValidationException이 발생하도록 표시합니다. 그러나 WebSphere® Application Server 는 여러 팀이 응용프로그램 서버에 어셈블 및 전개된 모듈을 함께 개발하는 환경을 지원합니다. 이 환경에서 애플리케이션의 모든 EJB는 동일한 클래스 로더로 로드되고 모든 EJB 및 웹 서비스(WAR) 모듈이 단일 클래스 로더로 로드될 수 있도록 애플리케이션 클래스 로더를 구성할 수 있습니다. 이로 인해 제품은 동일한 클래스 경로에서 다중 validation.xml 파일 지원을 제공합니다.

Bean 유효성 검증 및 XML 디스크립터를 사용하는 애플리케이션이 여러 개의 EJB 모듈과 웹 모듈을 포함하는 경우, 각 validation.xml 파일은 해당 모듈에만 적용되는 유효성 검증 팩토리에 연관됩니다. 이 환경에서 정의되는 모든 constraint-mapping 요소는 validation.xml 파일이 정의된 모듈에서만 검색됩니다. 예를 들어, EJB 모듈 building.jar에 다음 제한조건을 정의하는 META-INF/validation.xml 파일 및 validation.xml 파일이 포함되는 경우 두 META-INF/constraints-house.xml 및 META-INF/constraints-rooms.xml 파일 모두 building.jar 파일에도 있어야 합니다.
<constraint-mapping>META-INF/constraints-house.xml</constaint-mapping>
<constraint-mapping>META-INF/constraints-rooms.xml</constraint-mapping>

이 동작의 예외는 모든 Bean 유효성 검증 제한조건 클래스 및 구성이 모든 애플리케이션 모듈에 표시됩니다. 한 개의 validation.xml 파일이 EAR 파일에 정의되고 다른 validation.xml 파일은 모듈의 클래스 경로에 표시되는 상황인 경우 유효성 검증기 팩토리 또는 유효성 검증기를 작성하는 모든 모듈은 EAR 파일에 정의되는 validation.xml 파일을 사용합니다. 그러면 클래스 경로가 구성된 경우 다른 모듈도 다른 모듈의 validation.xml 파일을 사용하는 유효성 검증기 팩토리를 작성할 수 있으며 두 모듈 모두 동일한 클래스 경로에 표시되고 한 개의 validation.xml 파일만 해당 모듈에 표시됩니다.

Bean 유효성 검증 API 및 메타데이터에 대한 자세한 정보는 JSR 349 Bean 유효성 검증 스펙 문서를 참조하십시오.