2014-07-15 49 views
14

下面是我遇到的映射方法,不管我向它傳遞什麼值,驗證返回「通過驗證」。使用hibernate驗證器驗證單個基本類型的Spring MVC

@RequestMapping(value = "test", method = RequestMethod.POST) 
@ResponseBody 
public String getTest(@RequestBody @Valid @Max(32) long longValue, BindingResult result) { 
    if (result.hasErrors()) { 
    return "failed validation"; 
    } else { 
    return "passed validation"; 
    } 
} 

我知道@Max工作與我的應用程序,因爲我用它來驗證對大量的數據返回到控制器的自定義對象。它只在這種情況下不會運行驗證,在這種情況下,我會調用@Valid和方法參數中對象的驗證類型。

這是不允許與休眠驗證程序?

我希望不必定義一個只包含一個long值的對象,以便我可以在其上運行驗證。

回答

3

我希望不必定義一個僅包含長 值的對象,以便我可以在其上運行驗證。

定義一個包裝bean會使IMHO成爲最聰明的舉動,因爲hibernate-validator完全以bean的概念爲中心,而且畢竟是bean驗證規範的參考實現。該規範的主要動機之一是確認跨越不同應用程序層的跨領域關注,並提供一種機制來優雅地處理此問題。這就是爲什麼它以bean爲中心的原因,它是通過圖層傳遞的對象。

在另一方面,程式設計驗證primitves不是什麼大不了的事畢竟,你的代碼可以簡單地像

@RequestMapping(value = "test", method = RequestMethod.POST) 
@ResponseBody 
public String getTest(@RequestBody long longValue, BindingResult result) { 
    if (longValue > 32) { 
    result.rejectValue("longValue", "error.longValue", "longValue max constrained failed"); 
    return "failed validation"; 
    } else { 
    return "passed validation"; 
    } 
} 

所以在我看來,無論是如果它足夠簡單去的程序化驗證,或者簡單地包裝該值。

+0

我不認爲在我的情況下,包裝選項將是最好的選擇,因爲我應該有一個包裝對於每個基元,字符串和所有其他單一基本類型的註釋。並驗證它在代碼中,我認爲它會很好,但我想保持一些連貫性,我驗證對象的方式。我想用hibernate驗證器或其中的任何一種驗證所有類型的對象......所以我不準備聽取hibernate驗證器不驗證這種事情:P謝謝你的回答! – jscherman

2

不,這是不允許的。我明白了你的觀點,然而JSR-303規範(休眠驗證器實現的)是用於bean驗證的,參見here

2

首先,如其他答案所述,Hibernate驗證器不允許直接驗證基元這個問題。爲了使用Hibernate Validator,定義一個包含long值的新類正是使用Hibernate Validator所需的。

其次,也是最重要的,然而,程序驗證是有效的,它非常簡單,它不乾淨並且不可缺少。讓我用一些例子來說明這一點:

@RequestMapping(value = "testA", method = RequestMethod.POST) 
@ResponseBody 
public String getTestA(@RequestBody long longValue, BindingResult result) { 
    if (longValue > 32) { 
    result.rejectValue("longValue", "error.longValue", "longValue max constrained failed"); 
    return "failed validation for test A"; 
    } else { 
    return "passed validation for test A"; 
    } 
} 


@RequestMapping(value = "testB", method = RequestMethod.POST) 
@ResponseBody 
public String getTestB(@RequestBody long longValue, BindingResult result) { 
    if (longValue > 32) { 
    result.rejectValue("longValue", "error.longValue", "longValue max constrained failed"); 
    return "failed validation for test B"; 
    } else { 
    return "passed validation for test B"; 
    } 
} 


@RequestMapping(value = "testC", method = RequestMethod.POST) 
@ResponseBody 
public String getTestC(@RequestBody long longValue, BindingResult result) { 
    if (longValue > 32) { 
    result.rejectValue("longValue", "error.longValue", "longValue max constrained failed"); 
    return "failed validation for test C"; 
    } else { 
    return "passed validation for test C"; 
    } 
} 

首先要注意的是,與3個簡單的函數,所有的驗證代碼是重複的。其次,如果在某些時候您的驗證要求發生變化,並且現在所有的長整數值都必須大於35,那麼您需要更改每一個驗證函數,並且在這個例子中非常簡單,因爲只有3個函數具有相同的驗證,但想象一下,它是100個功能,你執行相同的驗證,現在是痛苦的。因此,只需定義一個具有長值和驗證註釋的新類,並在每種方法上使用該類,即可刪除代碼重複,並且在驗證需求發生變化並在單一位置應用更改時,完成了代碼。

此外,爲一個特定的任務定義類沒有任何問題,事實上,這正是Single Responsability Principle告訴你要做的。

編輯:添加了指向SRP說明的鏈接。