복붙노트

[SPRING] Hibernate Validator를 사용하여 double과 float 값을 검증 - bean 검증

SPRING

Hibernate Validator를 사용하여 double과 float 값을 검증 - bean 검증

Spring 커맨드 빈에서 java.lang.Double 필드의 최대 값과 최소값을 검증하는 방법을 찾고 있습니다. 값은 주어진 값 범위 사이에 있어야합니다.

public final class WeightBean
{
     @Max(groups={ValidationGroup.class}, value=Double.MAX_VALUE, message="some key or default message")
     @Min(groups={ValidationGroup.class}, value=1D, message="some key or default message")
     private Double txtWeight;  //Getter and setter.

     public interface ValidationGroup{}         
}

그러나 @Max와 @Min은 java.lang.Double 값을 취할 수 없습니다.

그런 분야를 검증하는 방법은 무엇입니까?

나는 Spring 3.2.0과 Hibernate Validator 4.3.1 CR1을 가지고 일하고있다.

해결법

  1. ==============================

    1.주석을 사용할 수는 있지만, 결과에 따라 잘못된 결과가 나올 수 있습니다. 이것은 많은 경우에 double과 imo에 대한 일반적인 문제이며, _Double_s는 피해야합니다. 어쩌면 다른 유형으로 전환하는 것이 최선의 해결책입니까? BigDecimal 예를 들면?

    주석을 사용할 수는 있지만, 결과에 따라 잘못된 결과가 나올 수 있습니다. 이것은 많은 경우에 double과 imo에 대한 일반적인 문제이며, _Double_s는 피해야합니다. 어쩌면 다른 유형으로 전환하는 것이 최선의 해결책입니까? BigDecimal 예를 들면?

  2. ==============================

    2.BigDecimal (또는 BigInteger)로 전환 한 경우 @DecimalMin 또는 @DecimalMax를 사용할 수 있습니다. 그러나 이것은 여전히 ​​float 또는 double에 대한 해결책이 아닙니다.

    BigDecimal (또는 BigInteger)로 전환 한 경우 @DecimalMin 또는 @DecimalMax를 사용할 수 있습니다. 그러나 이것은 여전히 ​​float 또는 double에 대한 해결책이 아닙니다.

  3. ==============================

    3.필자는 double 및 float 유형을 피하고 정밀도와 스케일을 기반으로 BigDecimal 값의 유효성을 검사 할 수있는 사용자 정의 유효성 검사기를 구현했습니다.

    필자는 double 및 float 유형을 피하고 정밀도와 스케일을 기반으로 BigDecimal 값의 유효성을 검사 할 수있는 사용자 정의 유효성 검사기를 구현했습니다.

    제약 디스크립터.

    package constraintdescriptor;
    
    import constraintvalidator.BigDecimalRangeValidator;
    import java.lang.annotation.Documented;
    import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.ElementType.METHOD;
    import java.lang.annotation.Retention;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    import java.lang.annotation.Target;
    import javax.validation.Constraint;
    import javax.validation.Payload;
    
    @Target({METHOD, FIELD, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Constraint(validatedBy = BigDecimalRangeValidator.class)
    @Documented
    public @interface BigDecimalRange {
        public String message() default "{java.math.BigDecimal.range.error}";
        public Class<?>[] groups() default {};
        public Class<? extends Payload>[] payload() default {};
    
        long minPrecision() default Long.MIN_VALUE;
        long maxPrecision() default Long.MAX_VALUE;
        int scale() default 0;
    }
    

    제약 조건 발리 데이터.

    package constraintvalidator;
    
    import constraintdescriptor.BigDecimalRange;
    import java.math.BigDecimal;
    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    
    public final class BigDecimalRangeValidator implements ConstraintValidator<BigDecimalRange, Object> {
    
        private long maxPrecision;
        private long minPrecision;
        private int scale;
    
        @Override
        public void initialize(final BigDecimalRange bigDecimalRange) {
            maxPrecision = bigDecimalRange.maxPrecision();
            minPrecision = bigDecimalRange.minPrecision();
            scale = bigDecimalRange.scale();
        }
    
        @Override
        public boolean isValid(final Object object, final ConstraintValidatorContext cvc) {
            boolean isValid = false;
    
            if (object == null) { // This should be validated by the not null validator (@NotNull).
                isValid = true;
            } else if (object instanceof BigDecimal) {
                BigDecimal bigDecimal = new BigDecimal(object.toString());
                int actualPrecision = bigDecimal.precision();
                int actualScale = bigDecimal.scale();
                isValid = actualPrecision >= minPrecision && actualPrecision <= maxPrecision && actualScale <= scale;
    
                if (!isValid) {
                    cvc.disableDefaultConstraintViolation();
                    cvc.buildConstraintViolationWithTemplate("Precision expected (minimun : " + minPrecision + ", maximum : " + maxPrecision + "). Maximum scale expected : " + scale + ". Found precision : " + actualPrecision + ", scale : " + actualScale).addConstraintViolation();
                }
            }
    
            return isValid;
        }
    }
    

    필요한 경우 다른 유형에 대해서도 확장 할 수 있습니다.

    마지막으로 bean에서, BigDecimal 타입의 프로퍼티는 다음과 같이 @BigDecimalRange 주석으로 주석 될 수 있습니다.

    package validatorbeans;
    
    public final class WeightBean {
    
        @BigDecimalRange(minPrecision = 1, maxPrecision = 33, scale = 2, groups = {ValidationGroup.class}, message = "The precision and the scale should be less than or equal to 35 and 2 respectively.")
        private BigDecimal txtWeight; // Getter and setter.
    
        public interface ValidationGroup {}
    }
    
  4. ==============================

    4.때로는 javax.validation.constraints의 @AssertTrue / @AssertFalse와 쌍으로 편리하다.

    때로는 javax.validation.constraints의 @AssertTrue / @AssertFalse와 쌍으로 편리하다.

    public final class WeightBean {
        @NotNull
        private Double txtWeight;  //Getter and setter.
    
        @AssertTrue
        public boolean getTxtWeightCheck() {
            return txtWeight > 0.1 && txtWeight < 0.9;
        }
    }
    
  5. ==============================

    5.최대 절전 유효성 검사기 API의 @Digits도 사용할 수 있습니다

    최대 절전 유효성 검사기 API의 @Digits도 사용할 수 있습니다

    @Digits(integer = 10 /*precision*/, fraction = 2 /*scale*/)
    
  6. from https://stackoverflow.com/questions/15488990/validating-double-and-float-values-using-hibernate-validator-bean-validation by cc-by-sa and MIT license