Javax BigDecimal Validation – Javax BigDecimal验证

最后修改: 2019年 8月 10日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In the tutorial Java Bean Validation Basics, we saw how to apply basic javax validation to various types, and in this tutorial, we’ll focus on using javax validation with BigDecimal.

Java Bean验证基础教程中,我们看到了如何将基本的javax验证应用于各种类型,而在本教程中,我们将重点讨论如何将javax验证与BigDecimal一起使用。

2. Validating BigDecimal Instances

2.验证BigDecimal实例

Unfortunately, with BigDecimal, we can’t use the classic @Min or @Max javax annotations.

不幸的是,有了BigDecimal,我们不能使用经典的@Min@Max javax注释。

Luckily, we have a dedicated set of annotations for working with them:

幸运的是,我们有一套专门的注释来处理它们。

  • @DecimalMin

    @DecimalMin

  • @Digits

    @Digits

  • @DecimalMax

BigDecimal is the first choice for financial calculation because of its high precision.

BigDecimal金融计算的首选,因为其精度高

Let’s see our Invoice class, which has a field of type BigDecimal:

让我们看看我们的Invoice类,它有一个BigDecimal类型的域。

public class Invoice {

    @DecimalMin(value = "0.0", inclusive = false)
    @Digits(integer=3, fraction=2)
    private BigDecimal price;
    private String description;

    public Invoice(BigDecimal price, String description) {
        this.price = price;
        this.description = description;
    }
}

2.1. @DecimalMin

2.1. @DecimalMin.

The annotated element must be a number whose value is greater than or equal to the specified minimum. @DecimalMin has an attribute inclusive that indicates whether the specified minimum value is inclusive or exclusive.

被注释的元素必须是一个数值大于或等于指定的最小值的数字。 @DecimalMin有一个属性inclusive,表示指定的最小值是包容的还是排斥的。

2.2. @DecimalMax

2.2. @DecimalMax

@DecimalMax is the counterpart of @DecimalMin. The annotated element must be a number whose value is lower or equal to the specified maximum. @DecimalMax has an inclusive attribute that specifies whether the specified maximum value is inclusive or exclusive.

@DecimalMax@DecimalMin的对应部分。被注释的元素必须是一个数值低于或等于指定最大值的数字。@DecimalMax有一个inclusive属性,指定指定的最大值是包容的还是排斥的。

Also, @Min and @Max accept long values only. In @DecimalMin and @DecimalMax, we can specify the value in string format, which can be of any numeric type.

另外,@Min@Max只接受值。在@DecimalMin@DecimalMax中,我们可以以string格式指定数值,可以是任何数字类型。

2.3. @Digits

2.3@Digits

In many cases, we need to validate the number of digits in the integral part and fraction part of a decimal number.

在许多情况下,我们需要验证一个小数部分和分数部分的数字数量。

The @Digit annotation has two attributes, integer and fraction, for specifying the number of allowed digits in the integral part and fraction part of the number.

@Digit注解有两个属性,integerfraction,用于指定数字的integral部分和fraction部分的允许数字数

As per the official documentation, integer allows us to specify the maximum number of integral digits accepted for this number.

根据官方文档integer允许我们指定这个数字所接受的integral数字的最大数量

Similarly, the fraction attribute allows us to specify the maximum number of fractional digits accepted for this number.

同样,fraction属性允许我们指定该数字可接受的fractional数字的最大数量。

2.4. Test Cases

2.4.测试案例

Let’s see these annotations in action.

让我们看看这些注释的作用。

First, we’ll add a test that creates an Invoice with an invalid price according to our validation, and checks that the validation will fail:

首先,我们将添加一个测试,根据我们的验证创建一个价格无效的发票,并检查验证是否会失败。

public class InvoiceUnitTest {

    private static Validator validator;

    @BeforeClass
    public static void setupValidatorInstance() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void whenMoreThanThreeIntegerDigits_thenShouldGiveConstraintViolations() {
        Invoice invoice = new Invoice(new BigDecimal("1021.21"), "Book purchased");
        Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
        assertThat(violations).hasSize(1);
        assertThat(violations)
            .extracting("message")
            .containsOnly("numeric value out of bounds (<3 digits>.<2 digits> expected)");
    }
}

Now let’s check the validation with the correct price:

现在让我们用正确的价格检查一下验证情况。

@Test
public void whenLessThanThreeIntegerDigits_thenShouldNotGiveConstraintViolations() {
    Invoice invoice = new Invoice(new BigDecimal("10.21"), "Book purchased");
    Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
    assertThat(violations).isEmpty();
}

In a similar way, let’s see how validation works for the fractional part:

以类似的方式,让我们看看小数部分的验证是如何进行的。

@Test
public void whenTwoFractionDigits_thenShouldNotGiveConstraintViolations() {
    Invoice invoice = new Invoice(new BigDecimal("99.99"), "Book purchased");
    Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
    assertThat(violations).isEmpty();
}

@Test
public void whenMoreThanTwoFractionDigits_thenShouldGiveConstraintViolations() {
    Invoice invoice = new Invoice(new BigDecimal("99.999"), "Book purchased");
    Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
    assertThat(violations).hasSize(1);
    assertThat(violations)
        .extracting("message")
        .containsOnly("numeric value out of bounds (<3 digits>.<2 digits> expected)");
}

A price equal to 0.00 should violate our constraint:

一个等于0.00的价格应该违反我们的约束条件。

@Test
public void whenPriceIsZero_thenShouldGiveConstraintViolations() {
    Invoice invoice = new Invoice(new BigDecimal("0.00"), "Book purchased");
    Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
    assertThat(violations).hasSize(1);
    assertThat(violations)
        .extracting("message")
        .containsOnly("must be greater than 0.0");
}

Finally, let’s see the case with a price greater than zero:

最后,让我们看看价格大于零的情况。

@Test
public void whenPriceIsGreaterThanZero_thenShouldNotGiveConstraintViolations() {
    Invoice invoice = new Invoice(new BigDecimal("100.50"), "Book purchased");
    Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
    assertThat(violations).isEmpty();
}

3. Conclusion

3.总结

In this article, we saw how to use javax validation for BigDecimal.

在这篇文章中,我们看到了如何为BigDecimal使用javax验证。

All code snippets can be found over on GitHub.

所有的代码片段都可以在GitHub上找到