1. введение
В учебнике Основы валидации Java Bean мы рассмотрели , как применять базовую javax валидацию к различным типам, и в этом учебнике мы сосредоточимся на использовании javax валидации с BigDecimal .
2. Проверка экземпляров BigDecimal
К сожалению, с BigDecimal мы не можем использовать классические @Min или @Max аннотации javax.
К счастью, у нас есть специальный набор аннотаций для работы с ними:
@DecimalMin
@Цифры
- @DecimalMax
BigDecimal является первым выбором для финансовых расчетов из-за его высокой точности .
Давайте посмотрим на ваш Счет-фактура класс, который имеет поле типа 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
Аннотированный элемент должен быть числом, значение которого больше или равно указанному минимуму. |/@DecimalMin имеет атрибут inclusive , который указывает, является ли указанное минимальное значение включающим или исключающим.
2.2. @DecimalMax
@DecimalMax является аналогом @DecimalMin . Аннотированный элемент должен быть числом, значение которого меньше или равно указанному максимуму. @DecimalMax имеет атрибут inclusive , который указывает, является ли указанное максимальное значение включающим или исключающим.
Кроме того, @Min и @Max принимают только длинные значения. В @DecimalMin и @DecimalMax мы можем указать значение в формате string , которое может быть любого числового типа.
2.3. @Цифры
Во многих случаях нам нужно проверить количество цифр в интеграле части и дроби части десятичного числа.
Аннотация @Digit имеет два атрибута, целое число и дробь , для указания количества разрешенных цифр в интеграле части и дроби части числа .
Согласно официальной документации , integer позволяет нам указать максимальное количество целых цифр, принятых для этого числа . Но это верно только для не десятичных чисел. Для десятичных чисел он проверяет точное количество цифр в целой части числа. Мы увидим это в нашем тестовом примере.
Аналогично, атрибут fraction позволяет нам указать максимальное количество дробных цифр, принятых для этого числа.
2.4. Тестовые случаи
Давайте посмотрим на эти аннотации в действии.
Во-первых, мы добавим тест, который создаст счет-фактуру с недопустимой ценой в соответствии с нашей проверкой и проверит, что проверка завершится неудачей:
public class InvoiceUnitTest { private static Validator validator; @BeforeClass public static void setupValidatorInstance() { validator = Validation.buildDefaultValidatorFactory().getValidator(); } @Test public void whenPriceIntegerDigitLessThanThreeWithDecimalValue_thenShouldGiveConstraintViolations() { Invoice invoice = new Invoice(new BigDecimal(10.21), "Book purchased"); Set> violations = validator.validate(invoice); assertThat(violations.size()).isEqualTo(1); violations.forEach(action -> assertThat(action.getMessage()) .isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)")); } }
Теперь давайте проверим валидацию с правильной ценой, которая является целочисленным значением:
@Test public void whenPriceIntegerDigitLessThanThreeWithIntegerValue_thenShouldNotGiveConstraintViolations() { Invoice invoice = new Invoice(new BigDecimal(10), "Book purchased"); Set> violations = validator.validate(invoice); assertThat(violations.size()).isEqualTo(0); }
Если мы установим цену с более чем 3 цифрами в интегральной части, мы увидим ошибку проверки:
@Test public void whenPriceIntegerDigitGreaterThanThree_thenShouldGiveConstraintViolations() { Invoice invoice = new Invoice(new BigDecimal(1021.21), "Book purchased"); Set> violations = validator.validate(invoice); assertThat(violations.size()).isEqualTo(1); violations.forEach(action -> assertThat(action.getMessage()) .isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)")); }
Цена, равная 000.00, также должна подтверждать ограничение:
@Test public void whenPriceIsZero_thenShouldGiveConstraintViolations() { Invoice invoice = new Invoice(new BigDecimal(000.00), "Book purchased"); Set> violations = validator.validate(invoice); assertThat(violations.size()).isEqualTo(1); violations.forEach(action -> assertThat(action.getMessage()) .isEqualTo("must be greater than 0.0")); }
Наконец, давайте рассмотрим случай с ценой, которая больше 0:
@Test public void whenPriceIsGreaterThanZero_thenShouldNotGiveConstraintViolations() { Invoice invoice = new Invoice(new BigDecimal(100.50), "Book purchased"); Set> violations = validator.validate(invoice); assertThat(violations.size()).isEqualTo(0); }
3. Заключение
В этой статье мы рассмотрели, как использовать javax проверку для BigDecimal.
Все фрагменты кода можно найти на GitHub.