在 Spring 中使用双精度值进行验证

validation with double value in Spring

提问人:Ducthien 提问时间:2/17/2016 最后编辑:Ducthien 更新时间:11/16/2023 访问量:26131

问:

我想检查具有值的分数:0.00 <= value<= 10.00
我使用了:
-Model(Score):

 @Range(min = (long) 0.0, max = (long) 10.0)
 private double score;

-messages.properties:

Range.score.score=Please input 0<= score <=10

-servlet-context:.xml:

   <beans:bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource">
        <beans:property name="basename" value="messages" />
    </beans:bean>

但是值 = 10.01 已通过检查。
请帮帮我。

Java Spring 验证

评论

1赞 Kayaman 2/17/2016
答案是肯定的。强制转换为会将值截断为 ,使检查通过。10.01long10
0赞 Ducthien 2/17/2016
如何验证仅小于或等于 10 的值?
0赞 Kayaman 2/17/2016
不是,这是肯定的。@Range
0赞 Ducthien 2/17/2016
对不起,我不清楚你的建议。如果不能使用@Range我应该使用什么?
0赞 Kevin Cruijssen 2/17/2016
我想你正在使用 ,但我不确定。如果你是,我在 Max 的文档中看到以下内容:.唯一支持的小数是 ,所以也许使用 ?对于双人我不知道..org.hibernate.validator.constraints.Range"Note that double and float are not supported due to rounding errors (some providers might provide some approximative support)."BigDecimal@Range(min = new BigDecimal(0.0), max = new BigDecimal(10.0)) private BigDecimal score;

答:

1赞 hyness 2/18/2016 #1

有两个问题。第一个问题是您尝试在注释的属性中指定数据类型。您也不需要指定数据类型或分数,此注释仅接受整数。

此外,正如许多其他人所指定的,双精度和浮点数不允许四舍五入错误,因此您需要使用 BigDecimal 而不是双精度。BigDecimal 有一个 doubleValue() 方法,可以将值作为 double 获取。

@Range(min = 0, max = 10)
private BigDecimal score;
20赞 Ducthien 2/18/2016 #2

我用以下方式解决我的主张:

 @DecimalMax("10.0") @DecimalMin("0.0") 
 private double score;

非常感谢@Kayaman,@hyness

评论

10赞 6324 9/10/2017
的源代码还说...@DecimalMax@DecimalMinNote that {@code double} and {@code float} are not supported due to rounding errors
2赞 Akshay Anurag 8/22/2019
这是行不通的。查看 docs.oracle.com/javaee/7/api/javax/validation/constraints/...
0赞 Odwori 6/16/2022 #3

对于那些只想用消息进行约束的人

@DecimalMin(value = "1.0", message = "Please Enter a valid Deposit Amount")
0赞 Phanindra Gopishetty 11/16/2023 #4
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DoublePrecisionValidator.class)
public @interface DoublePrecision {
    String message() default "Invalid double precision";

    int precision() default 2;

    int maxDigits() default 10;

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

    Class<? extends Payload>[] payload() default {};
}

public class DoublePrecisionValidator implements ConstraintValidator<DoublePrecision, Double> {
    private int precision;
    private int maxDigits;

    @Override
    public void initialize(DoublePrecision doublePrecision) {
        this.precision = doublePrecision.precision();
        this.maxDigits = doublePrecision.maxDigits();
    }

    @Override
    public boolean isValid(Double value, ConstraintValidatorContext context) {
        if (value == null) {
            return true; // Null values are considered valid, add additional checks if needed
        }

        // Check precision
        double scaledValue = value * Math.pow(10, precision);
        long truncatedValue = (long) scaledValue;
        double restoredValue = truncatedValue / Math.pow(10, precision);

        // Check maxDigits
        String stringValue = Double.toString(value);
        int totalDigits = stringValue.length() - (stringValue.contains(".") ? 1 : 0);

        return value.equals(restoredValue) && totalDigits <= maxDigits;
    }
}