programing

두 개 이상의 필드를 조합하여 검증하려면 어떻게 해야 합니까?

goodsources 2022. 10. 1. 15:37
반응형

두 개 이상의 필드를 조합하여 검증하려면 어떻게 해야 합니까?

JPA 2.0/Hibernate 인증을 사용하여 모델을 검증하고 있습니다.다음 두 필드의 조합을 검증해야 하는 상황이 되었습니다.

public class MyModel {
    public Integer getValue1() {
        //...
    }
    public String getValue2() {
        //...
    }
}

다음 두 가지 경우 모델은 유효하지 않습니다.getValue1() ★★★★★★★★★★★★★★★★★」getValue2()null그렇지 않으면 유효합니다.

JPA 2.0 / Hibernate j j j j j j j j j j j j j j j j j j j j j j j j j j j?한 ★★★★★★★★★★★★★@NotNull주석 유효성 검사를 통과하려면 두 getter가 모두 취소되지 않아야 합니다.

여러 속성 검증의 경우 클래스 수준 제약 조건을 사용해야 합니다.Bean Validation Sneek 파트 II: 커스텀 제약:

클래스 레벨의 제약

여러 속성에 걸쳐 구속조건을 적용하거나 여러 속성에 따라 달라지는 구속조건을 표현하는 능력에 대해 우려를 표한 분도 계십니다.일반적인 예는 주소 검증입니다.주소에는 복잡한 규칙이 있습니다.

  • 거리 이름은 어느 정도 표준적이며 반드시 길이 제한이 있어야 한다
  • 우편번호 구조는 전적으로 국가에 달려 있다
  • 도시는 종종 우편번호와 관련지어 몇 가지 오류를 확인할 수 있습니다(검증 서비스에 액세스할 수 있는 경우).
  • 이러한 상호의존성 때문에 단순한 재산 수준 제약이 그 청구서에 적합하도록 한다.

Bean Validation 사양에서 제공하는 솔루션은 두 가지입니다.

  • 그룹 및 그룹 시퀀스를 사용하여 제약 조건 세트를 다른 제약 조건 세트보다 먼저 적용할 수 있습니다.이 주제는 다음 블로그 엔트리에서 다룹니다.
  • 클래스 레벨의 제약을 정의할 수 있습니다.

클래스 레벨 제약은 속성이 아닌 클래스에 적용되는 일반 제약 조건(주석/실장 듀오)입니다.은, 인스턴스를 isValid.

@AddressAnnotation 
public class Address {
    @NotNull @Max(50) private String street1;
    @Max(50) private String street2;
    @Max(10) @NotNull private String zipCode;
    @Max(20) @NotNull String city;
    @NotNull private Country country;
    
    ...
}

@Constraint(validatedBy = MultiCountryAddressValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AddressAnnotation {
    String message() default "{error.address}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

public class MultiCountryAddressValidator implements ConstraintValidator<AddressAnnotation, Address> {
    public void initialize(AddressAnnotation constraintAnnotation) {
    // initialize the zipcode/city/country correlation service
    }

    /**
     * Validate zipcode and city depending on the country
     */
    public boolean isValid(Address object, ConstraintValidatorContext context) {
        if (!(object instanceof Address)) {
            throw new IllegalArgumentException("@AddressAnnotation only applies to Address objects");
        }
        Address address = (Address) object;
        Country country = address.getCountry();
        if (country.getISO2() == "FR") {
            // check address.getZipCode() structure for France (5 numbers)
            // check zipcode and city correlation (calling an external service?)
            return isValid;
        } else if (country.getISO2() == "GR") {
            // check address.getZipCode() structure for Greece
            // no zipcode / city correlation available at the moment
            return isValid;
        }
        // ...
    }
}

, 에 의해 .MultiCountryAddressValidator오브젝트 인스턴스에 액세스함으로써 클래스 레벨의 제약조건은 유연성이 높고 관련된 여러 속성을 검증할 수 있습니다.여기에서는 주문은 생략되어 있으므로 다음 투고에서 다시 설명하겠습니다.

전문가 그룹은 다양한 다중 속성 지원 접근법에 대해 논의해 왔습니다.클래스 레벨 제약 접근법은 의존관계를 포함하는 다른 속성 레벨 접근법에 비해 충분한 단순성과 유연성을 제공한다고 생각합니다.의견을 보내주시면 감사하겠습니다.

Bean Validation을 올바르게 사용하기 위해 Pascal Thivent의 답변에 제공된 예를 다음과 같이 다시 쓸 수 있습니다.

@ValidAddress
public class Address {

    @NotNull
    @Size(max = 50)
    private String street1;

    @Size(max = 50)
    private String street2;

    @NotNull
    @Size(max = 10)
    private String zipCode;

    @NotNull
    @Size(max = 20)
    private String city;

    @Valid
    @NotNull
    private Country country;

    // Getters and setters
}
public class Country {

    @NotNull
    @Size(min = 2, max = 2)
    private String iso2;

    // Getters and setters
}
@Documented
@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = { MultiCountryAddressValidator.class })
public @interface ValidAddress {

    String message() default "{com.example.validation.ValidAddress.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
public class MultiCountryAddressValidator 
       implements ConstraintValidator<ValidAddress, Address> {

    public void initialize(ValidAddress constraintAnnotation) {

    }

    @Override
    public boolean isValid(Address address, 
                           ConstraintValidatorContext constraintValidatorContext) {

        Country country = address.getCountry();
        if (country == null || country.getIso2() == null || address.getZipCode() == null) {
            return true;
        }

        switch (country.getIso2()) {
            case "FR":
                return // Check if address.getZipCode() is valid for France
            case "GR":
                return // Check if address.getZipCode() is valid for Greece
            default:
                return true;
        }
    }
}

Bean Validation 사양(: 여기)을 준수하려면 커스텀클래스 레벨 검증기를 사용하는 것이 좋습니다.

Hibernate Validator 기능을 사용하는 경우 Validator-4.1.0 이후 제공되는 @ScriptAssert를 사용할 수 있습니다.최종. JavaDoc의 Excrpt:

스크립트 표현은 임의의 스크립트 언어 또는 표현 언어로 작성할 수 있습니다.이 경우 클래스 패스에 JSR 223("JavaTM Platform용 스크립트") 호환 엔진이 있습니다.

예:

@ScriptAssert(lang = "javascript", script = "_this.value1 != null || _this != value2)")
public class MyBean {
  private String value1;
  private String value2;
}

사용할 수 있습니다.@javax.validation.constraints.AssertTrue검증은 다음과 같습니다.

public class MyModel {
    
    private String value1;
    private String value2;

    @AssertTrue(message = "Values are invalid")
    private boolean isValid() {
        return value1 != null || value2 != null;
    }
}

프로그래밍 언어: Java

이것은 나에게 도움이 된 해결책이다.

요건:

  1. UI에는 FK 관계를 가진 여러 테이블/개체에 매핑하는 개체 목록이 포함된 테이블이 있습니다.

  2. 이제 검증은 여러 fks에서 수행되며 복제할 수 없는 열은 3개뿐입니다.3의 조합은 중복될 수 없습니다.

주의: Java에서 Custom Framework를 사용하고 있기 때문에 Hash Code 또는 동등한 것을 사용하는 옵션은 없습니다.어레이 인덱스 반복을 사용하면 불필요한 시간 복잡성이 증가합니다.

솔루션:

FK1#의 ID를 포함하는 커스텀 문자열인 String을 준비했습니다.FK2# 아이디FK3 Ex의 ID: 문자열은 -> 1000L#3000L#1300L#과 같이 형성됩니다.

이 String은 중복이 발생하면 false를 반환하는 set의 add()를 사용하여 세트에 추가합니다.

이 플래그를 기반으로 검증 메시지를 던질 수 있습니다.

이게 도움이 됐어요.DS가 도움이 되지 않을 수 있는 시나리오와 제약이 있습니다.

언급URL : https://stackoverflow.com/questions/2781771/how-can-i-validate-two-or-more-fields-in-combination

반응형