第一种方法:
@valid注解 不可分组校验,可以嵌套验证,用在方法、构造函数、方法参数和属性上 效果:校验错误以后会有默认的响应
给校验的bean后紧跟一个BindingResult,就可以获取到校验的结果
public class Person {
@NotEmpty(message="姓名不能为空")
private String name;
private int userId;
@Length(min=6,max=10,message="密码必须在6-10位之间")
private String password;
@Email(message="邮箱不符合格式")
private String email;
}
@PostMapping("/person")
public Object addPerson(@RequestBody @Valid Person person,
BindingResult result) {
if (result.hasErrors()) { // 如果有异常的话,就会返回
List<ObjectError> allErrors = result.getAllErrors(); //获取所有的异常信息
for (ObjectError error : allErrors) {
System.out.println(error.getCode() + "\t"
+ error.getDefaultMessage());
}
}
return person;
}
第二种方法:
@Validated:可以分组校验,不可嵌套验证,用在类、方法和方法参数上。不能用在属性上
@Validated需要分组校验
//创建两个接口 不需要实现 只是用来分组
public interface UpdateGroup {
}
public interface AddGroup {
}
public class Person {
@NotEmpty(message="姓名不能为空",groups = {AddGroup.class})
private String name;
private int userId;
@Length(min=6,max=10,message="密码必须在6-10位之间",groups = {AddGroup.class})
private String password;
@Email(message="邮箱不符合格式")
private String email;
}
@PostMapping("/person")
public Object addPerson(@RequestBody @Validated({AddGroup.class}) Person person) {
// 执行业务代码 自动校验
return person;
}
默认没有指定分组的校验注解,在分组校验情况@Validated({AddGroup.class})下不生效,只会在@Validated生效;
第三种方法:
自定义校验
1.编写一个自定义的检验注解
2.编写一个自定义的检验器 实现ConstraintValidator接口
3.关联自定义的校验器和自定义的校验注解
// NotBlank源码
@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
public @interface NotBlank {
String message() default "{javax.validation.constraints.NotBlank.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
/**
* Defines several {@code @NotBlank} constraints on the same element.
*
* @see NotBlank
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface List {
NotBlank[] value();
}
}
仿照写一个自定义的检验注解
@Documented
@Constraint(validatedBy = {ListValueConstraintValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.lv.common.valid.ListValue.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] vals() default { };
}
/*
然后我们需要创建一个ValidationMessages.properties 在这上面写上对应的message信息:
com.lv.common.valid.ListValue.message=请输入指定值
*/
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> set = new HashSet<>();
// 初始化方法
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
/**
* 判断是否检验成功
* @param value 是注解标注地方传过来的值 也就是需要验证的值
* @param context
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value); // set里是否包含value
}
}