基本用法不說了,網上例子不少,這裏主要介紹下比較特殊狀況下使用的方法。java
1. 分組spring
有的時候,咱們對一個實體類須要有多中驗證方式,在不一樣的狀況下使用不一樣驗證方式,好比說對於一個實體類來的id來講,保存的時候是不須要的,對於更新時是必須的,能夠以下配置:app
public class UserModel { @NotNull(message = "{id.empty}", groups = { First.class }) private int id; @NotNull(message = "{username.empty}", groups = { First.class, Second.class }) private String username; @NotNull(message = "{content.empty}", groups = { First.class, Second.class }) private String content; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } public interface First { } public interface Second { }
經過 groups 對驗證進行分組測試
在controler中的代碼以下:this
@RequestMapping(value = "/save.action", method = RequestMethod.POST) public String save(@Validated( { Second.class }) UserModel userModel, BindingResult result) { if (result.hasErrors()) { return "validate/error"; } return "redirect:/success"; } @RequestMapping(value = "/update.action", method = RequestMethod.POST) public String update(@Validated( { First.class, Second.class }) UserModel user, BindingResult result) { if (result.hasErrors()) { return "validate/error"; } return "redirect:/success"; }
2. 組序列.net
默認狀況下,不一樣組別的約束驗證是無序的,然而在某些狀況下,約束驗證的順序卻很重要,以下面兩個例子:(1)第二個組中的約束驗證依賴於一個穩定狀態來運行,而這個穩定狀態是由第一個組來進行驗證的。(2)某個組的驗證比較耗時,CPU 和內存的使用率相對比較大,最優的選擇是將其放在最後進行驗證。所以,在進行組驗證的時候尚需提供一種有序的驗證方式,這就提出了組序列的概念。code
一個組能夠定義爲其餘組的序列,使用它進行驗證的時候必須符合該序列規定的順序。在使用組序列驗證的時候,若是序列前邊的組驗證失敗,則後面的組將再也不給予驗證。對象
下例中聲明瞭組 GroupA.class,GroupB.class 和 Group.class,其中 default,GroupA,GroupB 均爲 Group 的序列。ip
public interface GroupA { } public interface GroupB { } @GroupSequence( { Default.class, GroupA.class, GroupB.class }) public interface Group { } public class User { @NotEmpty(message = "firstname may be empty") private String firstname; @NotEmpty(message = "middlename may be empty", groups = Default.class) private String middlename; @NotEmpty(message = "lastname may be empty", groups = GroupA.class) private String lastname; @NotEmpty(message = "country may be empty", groups = GroupB.class) private String country; }
@RequestMapping(value = "/update.action", method = RequestMethod.POST) public String register(@Validated(Group.class) User user, BindingResult result) { if (result.hasErrors()) { return "validate/error"; } return "redirect:/success"; }
3. 驗證多個對象內存
當咱們在一個功能處理方法上須要驗證多個模型對象時,須要經過以下形式來獲取驗證結果:
@RequestMapping("/validate/multi") public String multi(@Valid @ModelAttribute("a") A a, BindingResult aErrors, @Valid @ModelAttribute("b") B b, BindingResult bErrors) { if (aErrors.hasErrors()) { //若是a模型對象驗證失敗 return "validate/error"; } if (bErrors.hasErrors()) { //若是a模型對象驗證失敗 return "validate/error"; } return "redirect:/success"; }
每個模型對象後邊都須要跟一個Errors或BindingResult對象來保存驗證結果,其方法體內部能夠使用這兩個驗證結果對象來選擇出錯時跳轉的頁面或處理的邏輯。
4. Junit測試
當自定義拓展Validation時,能夠使用以下方法進行測試:
@Test public void testValidate() { AnnotationDescriptor<EqualsAny> descriptor = new AnnotationDescriptor<EqualsAny>(EqualsAny.class); EqualsAny equalsAny = AnnotationFactory.create(descriptor); EqualsAnyValidator equalsAnyValidator = new EqualsAnyValidator(); equalsAnyValidator.initialize(equalsAny); Assert.assertTrue(equalsAnyValidator.isValid("123", null)); }
另外再講一點spring對自定義JSR-303限制類型支持的新特性,那就是Spring支持往ConstraintValidator裏面注入bean對象。例如在EqualsAnyValidator中利用@Resource註解注入其餘Bean對象。