基本用法不说了,网上例子不少,这里主要介绍下比较特殊状况下使用的方法。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对象。