2011-08-04 64 views
4

我使用JSR-303 bean驗證和Spring 3,我需要根據用例爲註釋提供不同的值。參數化JSR-303驗證值

例如,@Size(min=?)中的參數min的值必須爲1才能進行某些驗證,而對於另一種情況則必須爲5,並且我想從屬性文件中讀取此值。

我知道郵件參數可以從ValidationMessages.properties文件中讀取,如果作爲關鍵字提供的話,那麼其他參數呢?

回答

3

註釋參數的值只能是編譯時間表達式。這意味着對於@Size(min=X, max=Z),X和Z必須在編譯時可解析。

由於minmax@Size上被聲明爲int,所以您被卡住了。

如果您需要min,的不同值,我個人會看到兩種方法:。您可以對驗證器使用分組。使用min=1的一個組和min=5的一個組。例如,讓我們考慮一個Test類:

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 {} 

然後創建一些測試對象加驗證去用它:

Test test = new Test(); 
test.setProp("XY"); 

ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
Validator validator = factory.getValidator(); 

然後使用組驗證:

Set<ConstraintViolation<Test>> resultOne = validator.validate(test, GroupOne.class); 
Set<ConstraintViolation<Test>> resultTwo = validator.validate(test, GroupTwo.class); 

第一種情況自min=1"XY".length() == 2起有效,但第二種情況會因爲min=5而失敗。

這種方法涉及手動做驗證,我不認爲你可以僅僅依靠@Valid@RequestMapping標註的方法做驗證(因爲@Valid僅僅是沒有辦法提所需組的驗證觸發用於驗證)。幸運的是,Spring很靈活,並且自己調用驗證器的開銷不會太大。

我看到的第二個選項涉及使用自定義驗證器創建您自己的驗證註釋以進行匹配。 Here you can find a simple example to get you started。使用此解決方案,您可以聲明minmax作爲驗證器在驗證之前在捆綁中解析的字符串鍵。儘管這個解決方案比第一個更具開銷。

+1

我認爲自定義註釋+驗證器是通向這裏的路。他可以實現一個'@ DynMin'註解,這個註解將被稱爲'@DynMin(min =「{my.property.somewhere}」),並且使用了一個自定義的驗證器類,它將讀取屬性並驗證它(使用引用例如實現驗證程序)。 –

3

正如dpb所述,您可以使用validation groups來指定具有不同屬性值的相同約束。

如果您正在使用Hibernate Validator作爲BV實施的基礎,那麼您可以使用programmatic API而不是註釋來定義您的約束。這樣你可以像這樣在運行時檢索具體的約束值:

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();