Java 可参数化JSR-303验证值
我使用JSR-303bean验证和Spring3,我需要根据用例为注释提供不同的值 例如,Java 可参数化JSR-303验证值,java,spring,bean-validation,Java,Spring,Bean Validation,我使用JSR-303bean验证和Spring3,我需要根据用例为注释提供不同的值 例如,@Size(min=?)中min参数的值在某些验证中必须为1,在另一种情况下必须为5,我想从属性文件中读取此值 我知道如果作为键提供,消息参数可以从ValidationMessages.properties文件中读取,但是其他参数呢?注释参数的值只能是编译时表达式。这意味着对于@Size(min=X,max=Z)X和Z必须在编译时解析 由于@Size上的min和max被声明为int,因此您被卡住了 如果您需
@Size(min=?)
中min
参数的值在某些验证中必须为1,在另一种情况下必须为5,我想从属性文件中读取此值
我知道如果作为键提供,消息参数可以从
ValidationMessages.properties
文件中读取,但是其他参数呢?注释参数的值只能是编译时表达式。这意味着对于@Size(min=X,max=Z)
X和Z必须在编译时解析
由于@Size
上的min
和max
被声明为int
,因此您被卡住了
如果您需要不同的min
,我个人认为有两种方法
首先,您可以在验证器上使用分组。一组用于min=1
,一组用于min=5
。例如,让我们考虑<代码>测试< /代码>类:
public class Test {
@NotNull
@Size.List({
@Size(min = 1, groups = GroupOne.class),
@Size(min = 5, groups = GroupTwo.class)
})
private String prop;
public String getProp() {
return prop;
}
public void setProp(String prop) {
this.prop = prop;
}
}
您必须声明以下组:
public interface GroupOne {}
public interface GroupTwo {}
Set<ConstraintViolation<Test>> resultOne = validator.validate(test, GroupOne.class);
Set<ConstraintViolation<Test>> resultTwo = validator.validate(test, GroupTwo.class);
然后创建一些测试对象和验证程序:
Test test = new Test();
test.setProp("XY");
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
然后使用以下组进行验证:
public interface GroupOne {}
public interface GroupTwo {}
Set<ConstraintViolation<Test>> resultOne = validator.validate(test, GroupOne.class);
Set<ConstraintViolation<Test>> resultTwo = validator.validate(test, GroupTwo.class);
Set resultOne=validator.validate(test,GroupOne.class);
Set resultTwo=validator.validate(test,GroupTwo.class);
第一种情况有效,因为min=1
和“XY”.length()==2
,但第二种情况将失败,因为min=5
此方法涉及手动执行验证,我不认为您可以仅依靠@RequestMapping
注释方法上的@Valid
来执行验证(因为@Valid
只是验证的触发器,没有提及验证所需的组)。幸运的是,Spring非常灵活,自己调用验证器不会有太多开销
我看到的第二个选项涉及使用自定义验证器创建自己的验证注释以匹配。使用此解决方案,您可以将
min
和max
声明为字符串键,您的验证器将在验证之前在捆绑包中解析这些字符串键。不过,此解决方案比第一个解决方案的开销更大。如dpb所述,您可以使用不同的属性值指定相同的约束
如果您正在使用as BV实现,基于此,您可以使用代替注释来定义约束。这样,您可以在运行时检索具体的约束值,如下所示:
int minValue1 = ...; //read from properties file etc.
int minValue2 = ...;
//programmatically define the constraints for the Test type
ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Test.class )
.property( "prop", FIELD )
.constraint( new NotNullDef() )
.constraint( new SizeDef().min( minValue1 ).groups( GroupOne.class ) )
.constraint( new SizeDef().min( minValue2 ).groups( GroupTwo.class ) );
//retrieve a validator using the programmatic constraint mapping
HibernateValidatorConfiguration config =
Validation.byProvider( HibernateValidator.class ).configure();
config.addMapping( mapping );
ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();
我确实认为自定义注释+验证器是实现这一点的方法。他可以实现一个
@DynMin
注释,该注释将被称为“@DynMin(min=“{my.property.somewhere}”),并使用一个自定义的验证器类,该类将读取属性并对其进行验证(例如,使用引用实现验证器)。