我正在寻找一种方法来验证Spring命令bean中的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
值。
请注意,由于舍入错误,不支持double和float (某些提供商可能会提供一些近似支持)
那么验证这些字段的方法是什么?
我正在使用Spring 3.2.0和Hibernate Validator 4.3.1 CR1。
答案 0 :(得分:8)
您可以使用注释,但是您可能会得到错误的结果。这是双打和imo的一般问题,在许多情况下应该避免使用_Double_s。也许换成不同的类型是最好的解决方案?例如 BigDecimal ?
答案 1 :(得分:6)
如果您已切换到BigDecimal(或BigInteger),则可以使用@DecimalMin或@DecimalMax。 但这仍然不是浮动或双重的解决方案。
答案 2 :(得分:3)
我避开了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 {}
}
答案 3 :(得分:1)
有时与来自@AssertTrue
@AssertFalse
/ javax.validation.constraints
配对很方便
public final class WeightBean {
@NotNull
private Double txtWeight; //Getter and setter.
@AssertTrue
public boolean getTxtWeightCheck() {
return txtWeight > 0.1 && txtWeight < 0.9;
}
}
答案 4 :(得分:0)
您也可以使用hibernate验证器API中的@Digits
@Digits(integer = 10 /*precision*/, fraction = 2 /*scale*/)
答案 5 :(得分:0)
较新版本的Hibernate Validator(至少6.0.17)在双精度版本上支持@DecimalMin/Max
注释
答案 6 :(得分:0)
Hibernate 验证器适用于 @DecimalMin/Max
和 Double
。但它们不是精确的数字,只是近似值,根据验证实现的不同,可能会有一些错误的结果。
验证的最佳方法是将 Float
类型与 BigDecimal
和 @DecimalMin
验证注释一起使用。