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.