Java 创建运行时约束并验证字段映射
我有一个输入字段的映射,我想通过在运行时创建动态约束来使用JSR-303验证它 假设我的地图的结构如下所示:Java 创建运行时约束并验证字段映射,java,bean-validation,hibernate-validator,Java,Bean Validation,Hibernate Validator,我有一个输入字段的映射,我想通过在运行时创建动态约束来使用JSR-303验证它 假设我的地图的结构如下所示: name: Foo description: Foo description 现在,如果我有一组存储在某种配置中的规则,它说: name: required: true minLength: 3 maxLength: 30 description: required: false maxLength: 200 我想使用在运行时根据上述配置创
name: Foo
description: Foo description
现在,如果我有一组存储在某种配置中的规则,它说:
name:
required: true
minLength: 3
maxLength: 30
description:
required: false
maxLength: 200
我想使用在运行时根据上述配置创建的约束来验证我的输入映射。我知道我们可以这样做(示例取自Hibernate Validator文档):
HibernateValidatorConfiguration配置=验证
.byProvider(HibernateValidator.class)
.configure();
ConstraintMapping ConstraintMapping=configuration.createConstraintMapping();
约束映射
.类型(汽车.等级)
.属性(“制造商”,字段)
.constraint(新的NotNullDef())
.物业(“许可证牌”,字段)
.ignoreAnnotations(true)
.constraint(新的NotNullDef())
.constraint(新的SizeDef().min(2).max(14))
Validator Validator=configuration.addMapping(constraintMapping)
.buildValidatorFactory()
但显然,这对java.util.Map
s不起作用,因为映射不是JavaBeans。那么我该怎么做呢?我考虑了一些事情(每种方法的缺点):
if
条件手动验证,并抛出ConstraintViolationException
(我将在这里重新设计很多轮子)我想知道在这种情况下你会怎么做。有太多的问题要回答,但我会尽力回答 动态创建的约束映射 正如示例所描述的,它是可用的。有两种方法可以创建自定义映射 以编程方式创建自定义约束映射 让我们假设有一个POJO
import java.util.Map;
公开课Foo{
私有地图规则;
公共映射getRules(){
退货规则;
}
公共无效集合规则(映射规则){
这个。规则=规则;
}
}
所描述的约束是:
- 地图不能为空
- 地图的最大尺寸为2
- 地图的键应至少为3个字符
- 值不能为空,并且
- 值必须最大为5个字符
@NotNull
@尺寸(最大值=3)
私有地图规则;
其约束映射为:
var配置=验证
.byProvider(HibernateValidator.class)
.configure();
ConstraintMapping ConstraintMapping=configuration.createConstraintMapping();
约束映射
.type(Foo.class)
.字段(“规则”)
.constraint(新的NotNullDef())
.constraint(新的SizeDef().max(2))
.containerElementType(0)
.constraint(新的SizeDef().min(3))
.containerElementType(1)
.constraint(新的NotBlankDef())
.constraint(新的SizeDef().max(5))
;
var validator=configuration.addMapping(constraintMapping)
.buildValidatorFactory()
.getValidator();
例如:
公共类测试{
@试验
无效名称(){
var配置=验证
.byProvider(HibernateValidator.class)
.configure();
ConstraintMapping ConstraintMapping=configuration.createConstraintMapping();
约束映射
.type(Foo.class)
.字段(“规则”)
.constraint(新的NotNullDef())
.constraint(新的SizeDef().max(2))
.containerElementType(0)
.constraint(新的SizeDef().min(3))
.containerElementType(1)
.constraint(新的NotBlankDef())
.constraint(新的SizeDef().max(5))
;
var validator=configuration.addMapping(constraintMapping)
.buildValidatorFactory()
.getValidator();
资产(
() -> {
var obj=新的Foo();
/*
预期的违规行为
映射为空
*/
var result=validator.validate(obj.stream().toList();
assertAll(“仅应违反@NotNull”,
()->assertEquals(1,result.size()),
()->assertEquals({jakarta.validation.constraints.NotNull.message}),
result.get(0).getMessageTemplate()
)
);
},
() -> {
var obj=新的Foo();
/*
预期的违规行为
地图包含的元素太多(最多:2个)
注意:键和值未经验证
*/
对象设置规则(映射(“名称1”、“描述1”、“名称2”、“描述2”、“名称3”、“描述3”));
var result=validator.validate(obj.stream().toList();
assertAll(“仅应违反@Size”,
()->assertEquals(1,result.size()),
()->assertEquals({jakarta.validation.constraints.Size.message}),
result.get(0).getMessageTemplate()
)
);
},
() -> {
var obj=新的Foo();
/*
预期的违规行为
第一个键太短(最小值:3)
第一个值为空
第二个值太长(最大值:5)
*/
对象设置规则(映射“aa”、“bbb”、“longValue”);
var result=validator.validate