我开始验证一个方法参数:if notValid then throw exception,
然后我意识到我可以创建自己的注解来验证参数,几分钟后我正在寻找一个已经有这些简单注解的库来验证数字。
我发现了 Jakarta Bean Validation(例如 javax.validation),
所以我添加了以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring-boot.version}</version>
</dependency>
我是通过注解一个方法参数开始使用它的。
public static String toString(
final BigDecimal numberToFormat,
@PositiveOrZero final int scale,
final char decimalSeparator,
final char groupingSeparator,
final NumberFormatPattern numberFormatPattern) {
String pattern = getPattern(scale, numberFormatPattern);
return format(numberToFormat, decimalSeparator, groupingSeparator, pattern);
}
开始 JUnit 测试并传递 -1 作为标度值,我原以为会抛出异常,但什么也没发生。
class NumberFormatUtilsTest {
void _toString_INVALID_SCALE() {
BigDecimal number = NumberUtils.toBigDecimal("123.456");
assertThrows(ConstraintViolationException.class, () -> NumberFormatUtils.toString(number, -1, ',', '.', DECIMALS_ALWAYS));
}
}
查看文档我看到:
注意声明这些约束不会自动导致 在调用相关方法时对它们进行验证。
为什么有人要在不执行验证的情况下添加约束?
不,我没有,因为正如我所说,我希望是自动的, 而不是我必须配置 bean 验证
很抱歉,它没有像您期望的那样工作。它需要配置 Bean Validation 并通过 Bean Validation API 触发验证。此外,它也不支持对静态方法进行验证。引自this如下:
约束只能应用于实例方法,即声明 不支持对静态方法的约束。取决于 您用于触发方法验证的拦截工具, 额外的限制可能适用,例如关于可见性 支持作为拦截目标的方法。请参阅 拦截技术的文档,以查明是否有 存在这样的限制。
好消息是 spring boot 已经自动配置它并为您完成所有必要的 Bean Validation 集成,但是您必须将它作为 spring bean 并通过使用
@Validated
注释来启用验证功能。所以更改为以下内容:
@Service
@Validated
public class NumberFormatUtils{
public String toString(
final BigDecimal numberToFormat,
@PositiveOrZero final int scale,
final char decimalSeparator,
final char groupingSeparator,
final NumberFormatPattern numberFormatPattern)
}
}
要使用它,您必须通过
NumberFormatUtils
从 spring 上下文中获取 @Autowired
bean 实例,而不是简单地自己创建实例。