2013-03-03 31 views
0

我是JSR 303 BV的忠實粉絲,但是在我當前的項目中,我有很多「依賴於上下文的驗證」,我沒有找到任何合理的方法來與BV實現它們。 基本上驗證規則可以取決於Bean驗證的上下文相關驗證

  • 登錄的用戶(它存儲在http請求)
  • 我們在充當一個用戶 - 用戶的ID是REST URL的路徑PARAM像/富/酒吧/用戶/ 1 /某物
  • 這兩種

一個小例子:

class Alphabet{ 
@Valid 
private Alpha a; 
@Valid 
private Beta b; 
@Valid 
private Gamma g; 
} 

而且validati on規則: 如果在URL中提供其ID的用戶具有角色「admin」,則「a」,「b」,「g」屬性都不能爲空。如果它具有角色「用戶」,則只有「一個」必須不爲空,而其他道具必須爲空。

所以基本上這些類型的規則可以很容易地實現爲Alphabet類的類級約束,但自定義驗證器需要以某種方式訪問​​URL中提供的用戶的id。有沒有什麼聰明的方法可以實現,或者我必須強制所有REST客戶端多次傳遞用戶ID:在URL中和有效負載中,所以後者將僅由BV使用。 更復雜的情況是,驗證規則依賴於登錄用戶,因此自定義驗證器必須以某種方式訪問​​已驗證的委託人 - 從ThreadLocal或HttpServletRequest。

回答

2

你可以利用validation groups

//Define validation groups 
interface AdminChecks {} 
interface UserChecks {} 

//Assign the constraints to the two groups 
class Alphabet{ 

    @NotNull(groups={AdminChecks.class, UserChecks.class}) 
    private Alpha a; 

    @NotNull(groups=AdminChecks.class) 
    @Null(groups=UserChecksChecks.class) 
    private Beta b; 

    @NotNull(groups=AdminChecks.class) 
    @Null(groups=UserChecksChecks.class) 
    private Gamma g; 
} 

根據當前用戶的角色,則請指定AdminChecksUserChecks當調用驗證,例如像這樣的管理員檢查:

Validator validator = ...; 
Set<ConstraintViolation<Alphabet>> violations = validator.validate(
    new Alphabet(), 
    AdminChecks.class 
); 
+0

Thx Gunnar for answer。我過分簡化了我的示例。真正的驗證規則如下:如果用戶是訪客並且屬於禁止更改客人的伽馬值的工作組,那麼伽瑪屬性必須爲空,但是如果工作組允許客人的伽馬變化比伽瑪的變化不能爲空。類似的規則適用於Beta,Alpha和其他屬性。所有這些屬性都是獨立的 - 您可以讓工作組允許客人使用gamma和beta,但不允許使用alpha - 任何可能的組合。我只是不能用驗證組對它進行建模,並且必須使用類級約束 – user62058 2013-03-07 06:39:43