1

我有一個dto對象,它使用第一個和最後一個字段來保持IP範圍。簡單的CRUD操作與使用dropwizard這個類(新澤西州傑克遜 - Hibernate驗證)Bean驗證 - 構造函數/工廠參數

public class IpRangeDto { 

    @JsonCreator 
    public static IpRangeDto fromCidr(@JsonProperty("cidr") String cidr) { 
     //Resolve CIDR and assign first and last fields 
    } 

    @NotNull 
    @IpAddress // My custom validator 
    private String first; 

    @NotNull 
    @IpAddress 
    private String last; 
} 

對於用戶友好的緣故,我決定加入的另一種方式來創建這個對象,這是通過使用CIDR製造。因此,客戶端可以發送JSON中的firstlast字段或僅發送cidr字段。因此,使用@JsonCreator的方式如上所述。它工作得很好。

"ipRange":{ 
    "first": "15.0.0.1", 
    "last": "15.0.0.255", 
} 

"ipRange":{ 
    "cidr": "15.0.0.0/24" 
} 

我要驗證此CIDR值,它是正確的格式,這樣我就可以適當的錯誤消息返回422。如果我在構造函數/工廠方法中拋出異常,那麼澤西 - 傑克遜直接返回400(即使我拋出ConstraintViolationException,它被封裝爲JsonProcessingException)。

我可以簡單地忽略這些異常,並將字段留空,由於@NotNull約束,這些字段將返回422,但這樣錯誤信息就不會像應該那樣清晰。

我試着在@JsonProperty參數旁邊添加我的@Cidr驗證程序,但這似乎並不奏效。我的理解是驗證發生在Jackson完成創建Dtos後,因此使用我的@JsonCreator方法可能沒有解決此問題的方法。所以我也開放重構建議。

回答

1

我不是一個將Bean Validation精確集成到傑克遜中的專家,但我認爲它只是在進行實際屬性驗證。這意味着如您已經指出的那樣,首先創建實體,然後對屬性進行驗證。

Bean驗證(從版本1.1開始)也提供所謂的方法驗證,在這種情況下,您可以將約束放在方法的字符串參數上,但如前所述,我認爲不存在集成在傑克遜爲此。

還有一件事情;-) - 靜態方法和屬性通常被排除在Bean驗證的驗證中(另請參閱http://beanvalidation.org/1.1/spec/#d0e2815)。

關於解決方法,想到一件事(即使感覺有點複雜)。編寫一個自定義類級別IpRange約束。在類限制中,您將得到一個IpRangeDto實例,您需要驗證整個對象併爲任何違規選擇正確的錯誤消息。假設你將一個cidr屬性添加到調用fromCidr時設置的dto中,那麼你將需要所有的信息來驗證和選擇正確的錯誤信息。