7

我正在寻找一种方法来验证Spring命令bean中的java.lang.Double字段的最大值和最小值(值必须位于给定的值范围之间),就像,使用Hibernate Validator验证double和float值 - bean验证

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。

+0

如果你想我可以在我的收藏约束在这里实现DoubleRangeValidator:http://waxolunist.github.com/validationconstraints/ - 只要打开一个问题,明天就可以在Maven中心进行。 – Christian 2013-03-20 15:03:05

+0

@ Waxolunist - 谢谢,但我没有得到。 – Tiny 2013-03-21 11:36:25

回答

7

您可以使用注释,但您可能会得到错误的结果。在许多情况下,这是一个普遍的问题,应该避免double_s和imo。也许切换到不同的类型是最好的解决方案?例如BigDecimal

+1

我已经切换到'BigDecimal'类型,但'@ Max'和'@ Min'的'value'属性只接受'Long'值。我需要检查,如果一个值在一个定义的范围之间。例如,从0.1开始到0.9。这对于bean验证不可行吗? – Tiny 2013-03-23 10:53:11

+4

对于'BigDecimal'请参阅'@ DecimalMin'注释。 – 2015-09-19 11:48:11

3

我已经避免了doublefloat类型,并实现了一个自定义验证程序,该验证程序可以验证基于精度和比例的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; 
    } 
} 

这可以扩展为其他类型,以及在需要时。


终于在豆,类型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 {} 
} 
0

您也可以使用从Hibernate验证API @Digits以及

@Digits(integer = 10 /*precision*/, fraction = 2 /*scale*/)