spring 使用 Hibernate Validator 验证 double 和 float 值 - bean 验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15488990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Validating double and float values using Hibernate Validator - bean validation
提问by Tiny
I'm looking for a way to validate a java.lang.Doublefield in the Spring command bean for its maximum and minimum values (a value must lie between a given range of values) like,
我正在寻找一种方法来验证java.lang.DoubleSpring 命令 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{}
}
But both @Maxand @Mincannot take a java.lang.Doublevalue.
但两者@Max并@Min不能取java.lang.Double值。
Note that double and float are not supported due to rounding errors (some providers might provide some approximative support)
请注意,由于舍入错误,不支持 double 和 float(某些提供商可能会提供一些近似支持)
So what is the way of validating such fields?
那么验证这些字段的方法是什么?
I'm working with Spring 3.2.0 and Hibernate Validator 4.3.1 CR1.
我正在使用 Spring 3.2.0 和 Hibernate Validator 4.3.1 CR1。
采纳答案by Hardy
You can use the annotation, but you might get false results depending. This is a general problem with doubles and imo in many cases _Double_s should be avoided. Maybe switching to a different type is the best solution? BigDecimalfor example?
您可以使用注释,但可能会得到错误的结果,具体取决于。在许多情况下,这是双打和 imo 的普遍问题,应该避免 _Double_s。也许切换到不同的类型是最好的解决方案?例如BigDecimal?
回答by Sebastian
If you have switched to BigDecimal (or BigInteger), you could use @DecimalMinor @DecimalMax. But this is still no solution for float or double.
如果您已切换到 BigDecimal(或 BigInteger),则可以使用@DecimalMin或@DecimalMax。但这仍然不是 float 或 double 的解决方案。
回答by Tiny
I have avoided the doubleand the floattypes and implemented a custom validator that could validate a BigDecimalvalue based on the precision and the scale.
我避免了double和float类型并实现了一个自定义验证器,它可以BigDecimal根据精度和比例验证一个值。
The constraint descriptor.
约束描述符。
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;
}
The constraint validator.
约束验证器。
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;
}
}
This could be extended for other types as well, as and when required.
这也可以在需要时扩展到其他类型。
And finally in the bean, the property of the type BigDecimalcould be annotated by the @BigDecimalRangeannotation as follows.
最后在 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 {}
}
回答by Leonid Muzyka
Sometimes it's convenient in pair with @AssertTrue/ @AssertFalsefrom javax.validation.constraints
有时与@AssertTrue/ @AssertFalsefrom配对很方便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;
}
}
回答by FearlessHyena
You can also use @Digitsfrom the hibernate validator API as well
您也可以@Digits从休眠验证器 API 中使用
@Digits(integer = 10 /*precision*/, fraction = 2 /*scale*/)
回答by Flame239
Newer versions of Hibernate Validator (at least 6.0.17) supports @DecimalMin/Maxannotation on double
较新版本的 Hibernate Validator(至少 6.0.17)支持@DecimalMin/Max双注注释
请参阅类以进行验证

