2016-08-02 36 views
0

我有以下注釋如何參數化Hibernate Constraint消息以包含字段名稱?

@Target({ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = IdValidator.class) 
public @interface Id { 
    String message() default "{Id field cannot be null}"; 
} 

,我使用我的類

public class Person { 
    @Id 
    String firstName; 
    @Id 
    String lastName; 
} 

當我打電話

ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
validator = factory.getValidator(); 
Set<ConstraintViolation<FakePerson>> violations = validator.validate(person); 

我想ConstrainstViolation有一個消息,說「名字不能爲空」。我怎樣才能做到這一點?

有沒有一種方法可以創建與ConstraintValidator中的路徑相關聯的消息?

public class IdValidator implements ConstraintValidator<Id, Object> { 
    @Override 
    public boolean isValid(Object value, ConstraintValidatorContext context) 
    { 
    //Ideally I can build the messages associate with the property here with ConstraintValidatorContext 
    } 
} 

回答

0

有幾個選項。

第一種方法是在註釋中添加一個新屬性,如下所示爲label

@Target({ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = PKFieldValidator.class) 
public @interface Id { 
    String message() default "{Id field cannot be null}"; 
    String label(); 
} 

然後在課堂上,你會使用

@Id(label="firstName") 
private String firstName; 
@Id(label="lastName") 
private String lastName; 

然後,只需讓你的消息是這樣的

Id.message={label} is required. 

但這種做法的問題是,你正在下降將bean字段名稱轉換爲可能是其他語言的翻譯。 Se requiere el firstName在西班牙語中有多大意義?

我的首選建議是實際保留bean驗證消息的一般性。諸如Field is requiredMust be greater than 0之類的東西對我來說似乎很合理,並允許重複使用。

對於需要將這些違規消息與屬性相關聯的情況,只需遍歷違規,獲取propertyPath並將路徑加上消息打印到您的日誌或內容。

從web框架中,我更願意這樣做,迭代約束違規,將它們添加到Map<String,String>,其中密鑰爲propertyPath,值爲違規消息。然後在用戶界面中,我將該消息與每個字段的輸入控件相關聯,從而使事物保持簡潔,簡潔,用戶易於理解和閱讀。

+0

我忘記提到這個問題,但我希望有一種方法可以在'ConstraintValidator.isValid()'中獲得'propertyPath',這樣可以在一個地方定義消息。如果我們在得到'Set >違規後生成消息,那麼我們必須做到這一切。 – Glide

+0

將異常處理邏輯封裝到單獨的類並調用它。在許多情況下,我們都需要執行異常類轉換(JPA異常的內部異常)或需要集中控制器異常處理的情況。如果你想作爲構建後編譯步驟,你也可以使用AspectJ。 – Naros

相關問題