分组验证
通过前面的文章,我们了解到我们的验证注解都是加在我们对应要验证的JavaBean对应的字段上的。但这有一个问题存在,我们对同一个JavaBean可能不只验证它的新增,可能还会有修改,查询等,而各个操作对应的验证规则可能不一样。这就可以使用分组验证。
使用分组验证
1.定义用于分组的接口
public interface GroupOne {}
public interface GroupTow{}
分组接口就是两个普通的接口,用于标识,类似于java.io.Serializable
2.在验证注解中使用groups属性划定分组
@NotNull
@Min(message = "年龄不能小于{value}岁",value = 10,groups = GroupOne.class)
@Max(message = "{message.ValidTestBean.age.max}",value = 150,groups = GroupOne.class)
@Min(message = "司机年龄不能小于{value}岁",value = 18,groups = GroupTow.class)
@Max(message = "司机年龄不能大于{value}岁",value = 70,groups = GroupTow.class)
private int age;
age属性,我们用GroupOne和GroupTow划分为了两组验证
Controller使用分组
@RequestMapping("test1")
public void test1(@RequestBody @Validated(GroupTow.class) UserDTO bean, BindingResult errors){
System.out.println(errors.hasErrors()+"======hasErrors");
System.out.println(errors.hasFieldErrors()+"=====fieldErrors");
for(FieldError error : errors.getFieldErrors()){
System.out.println("验证的字段名称:"+error.getField());
System.out.println("验证规则名称:" + error.getCode());
System.out.println("提示信息:" + error.getDefaultMessage());
System.out.println("参数名称:" + error.getObjectName());
for(Object obj : error.getArguments()){
System.out.println("=======" + obj);
}
for(String str : error.getCodes()){
System.out.println("+++++++"+str);
}
}
}
注意是@Validated不是@Valid,分组验证需要使用@Validated,@Validated的value属性是分组接口的class对象数组。也就是说@Validated可以指定多个分组,如:@Validated({GroupOne.class,GroupTow.class}),这样我们可以通过合理的组合,达到我们分组验证的目的。
默认分组
我们之前的代码,在验证注解上没有添加groups属性,那么他们就是默认分组,javax.validation.groups.Default
组的继承
我们定义的组都是interface,是interface我们就可以继承
public interface GroupThree extends GroupOne{}
如果不做其他修改,直接在Controller中使用
@RequestBody @Validated(GroupThree.class) UserDTO bean
那么改验证将和GroupOne的验证结果一样
继承可以继承javax.validation.groups.Default
组的顺序
我们可以使用@GroupSequence注解来规定分组的验证顺序
@GroupSequence({ Default.class, CarChecks.class, DriverChecks.class })
public interface OrderedChecks {
}
或者在JavaBean上使用
@GroupSequence({GroupOne.class,GroupTow.class})
public class UserDTO {
@NotNull
private String name;
@NotNull
@Min(message = "年龄不能小于{value}岁",value = 10,groups = GroupOne.class)
@Max(message = "{message.ValidTestBean.age.max}",value = 150,groups = GroupOne.class)
@Min(message = "司机年龄不能小于{value}岁",value = 18,groups = GroupTow.class)
@Max(message = "司机年龄不能大于{value}岁",value = 70,groups = GroupTow.class)
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
级联验证
在JavaBean要验证的Object类型字段上添加@Valid注解,使添加了该注解的类也进行验证
import com.yyoo.springmvc.bean.groups.GroupOne;
import com.yyoo.springmvc.bean.groups.GroupTow;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public class UserDTO {
@NotNull
private String name;
@NotNull
@Min(message = "年龄不能小于{value}岁",value = 10,groups = GroupOne.class)
@Max(message = "{message.ValidTestBean.age.max}",value = 150,groups = GroupOne.class)
@Min(message = "司机年龄不能小于{value}岁",value = 18,groups = GroupTow.class)
@Max(message = "司机年龄不能大于{value}岁",value = 70,groups = GroupTow.class)
private int age;
@Valid
private OrgDTO orgDTO;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public OrgDTO getOrgDTO() {
return orgDTO;
}
public void setOrgDTO(OrgDTO orgDTO) {
this.orgDTO = orgDTO;
}
}
import com.yyoo.springmvc.bean.groups.GroupThree;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
public class OrgDTO {
@NotNull
private String name;
@Length(min = 5,max = 10,message = "部门地址在{min}到{max}个字符之间",groups = GroupThree.class)
private String loc;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
@RestController
@RequestMapping("validate")
public class Demo3Controller {
@RequestMapping("test1")
public void test1(@RequestBody @Validated(GroupThree.class) UserDTO bean, BindingResult errors){
System.out.println(errors.hasErrors()+"======hasErrors");
System.out.println(errors.hasFieldErrors()+"=====fieldErrors");
for(FieldError error : errors.getFieldErrors()){
System.out.println("验证的字段名称:"+error.getField());
System.out.println("验证规则名称:" + error.getCode());
System.out.println("提示信息:" + error.getDefaultMessage());
System.out.println("参数名称:" + error.getObjectName());
for(Object obj : error.getArguments()){
System.out.println("=======" + obj);
}
for(String str : error.getCodes()){
System.out.println("+++++++"+str);
}
}
}
}
关于级联验证的补充
@NotNull
@Valid
private OrgDTO orgDTO;
@NotNull
@Valid
private List<OrgDTO> list;
在要验证的引用字段上一般需要加上@NotNull来避免orgDTO字段为空的情况
验证集合类型的字段,也可以使用@Valid注解