2014-07-13 66 views
0

如果我有一個類,並且想要檢查該類中某個屬性的輸入是否在列表中,那麼我該怎麼做?列表中的Java驗證

public class Length { 

    public static final List<String> ALLOWABLE_UNITS = 
     Collections.unmodifiableList(Arrays.asList("inches", "feet", "meters", "millimeters")); 

    public BigDecimal lengthValue; 

    @SomeMatchingAnnotation(ALLOWABLE_UNITS) 
    public String lengthUnit; 
} 

有註解做到這一點?我需要創建自己的?

+2

'ALLOWABLE_UNITS.contains(lengthUnit)' –

回答

1

在你的領域,你可以做這樣的驗證二傳手:如果您使用JSR-303來驗證您的豆類,那麼你可以找一些自定義的驗證

public void setLengthUnit(String lengthUnit) { 
    if (!ALLOWABLE_UNITS.contains(lengthUnit) { 
    throw new IllegalArgumentException("Length unit not recognized."); 
    } 
    this.lengthUnit = lengthUnit; 
} 
+0

謝謝。我正在使用播放框架。它爲你創造了獲得者和制定者。你可以自己定義它們,但我希望不要這樣做,並使用現有的註釋。我編輯了我的問題。 – decapo

1

,自己寫一個,或只需使用javax.validation.constraints.Pattern

@Pattern(message="your message here" , regexp="^(meter|inch|cm)$") 
public String lengthUnit; 

更新

如果您想通過動態盟友建立了正確的值的數組,然後你應該使用自定義驗證。如果您使用Hibernate Validator作爲JSR-303供應商,那麼你可以選擇使用的@ScriptAssert註解,它允許您使用JSR-223兼容的腳本引擎定義約束:

@ScriptAssert(lang = "javascript", script = "_this.possibleValues.indexOf(_this.lengthUnit) > -1") 

請注意,我沒有跑上面的例子,但它應該按預期工作。

或者,您可以在即時模式下添加約束(仍然假設您使用Hibernate驗證)。

ConstraintMapping customMapping = new ConstraintMapping(); 
customMapping.type(Length.class).property("lengthUnit", FIELD).constraint(new PatternDef().regexp("^(mm|cm|inch)$")); 

HibernateValidatorConfiguration cfg = Validation.byProvider(HibernateValidator.class).configure(); 
cfg.addMapping(customMapping); 

ValidatorFactory vf = cfg.buildValidatorFactory(); 
Validator validator = vf.getValidator() 
+0

謝謝。但是,我沒有建立一個能夠將該數組傳遞給該註釋的正確方法嗎?我將不得不創建自己的驗證註釋? – decapo

+0

@decapo查看最新更新 –

0

編寫自定義Hibernate Validator是一個不錯的選擇。如果您選擇使用它,請將hibernate-validator JAR放在您的類路徑中。我在本例中使用了最新版本5.1.1.Final。

有很多的代碼必須被顯示爲它工作,但它確實三個部分:

  • 在球場上的批註指定,這是一個需要,
  • 要驗證的元素
  • 註釋本身的標準實現,以及
  • 該註釋和對象類型的ConstraintValidator的實現。

首先,豆:

public class Length { 

    @ValidUnit // this is the annotation we will use to validate. 
    private String inputUnit; 

    public String getInputUnit() { 
     return inputUnit; 
    } 

    public void setInputUnit(final String inputUnit) { 
     this.inputUnit = inputUnit; 
    } 
} 

字段爲String;我們需要記住,以備後用。

接下來是註釋。 Hibernate要求存在message(),groups()payload()。我相信JSR-303只需要這個信息。所以,我們會繼續實施,只實施我們認爲我們需要的幾件事情。

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
@Constraint(validatedBy = ValidUnitValidator.class) 
public @interface ValidUnit { 

    String message() default "Not a supported unit."; 

    Class<?>[] groups() default { }; 

    Class<? extends Payload>[] payload() default { }; 
} 

@Constraint註釋這個類以上告訴Hibernate使用該類型的驗證哪個類。所以,我們來實現它。

任何實施ConstraintValidator的聲明都是註釋和T類型。我們正在嘗試驗證String,因此我們在實施中將其替換爲T

public class ValidUnitValidator implements ConstraintValidator<ValidUnit, String> { 

    private final Set<String> validUnits = new HashSet<>(Arrays.asList("inches", "feet", "meters", "millimeters")); 

    @Override 
    public void initialize(final ValidUnit validUnit) { 
    } 

    @Override 
    public boolean isValid(final String value, final ConstraintValidatorContext constraintValidatorContext) { 
     return validUnits.contains(value); 
    } 
} 

最終,與直接驗證內聯的方法相比,它有點禮儀。但是,這可以讓你更好地區分顧慮;如果你想改變什麼是有效的單位(你可能想要添加光年),你只需要修改和測試一個類。