SpringBoot数据校验

SpringBoot数据校验

前提:要先引入validation依赖

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-validation</artifactId></dependency>

Validation 2.x 的22个注解

一、实体类DTO校验

1、第一种Controller内部捕捉校验信息

①第一步定义dto,所有校验都在dto的属性上进行。

public class ValidatorDto {    @NotEmpty(message = "名字不能为空!")    public String name;    @Email(message = "email格式不正确!")    public String email;    @Min(value = 10)    public int age;    @NotEmpty(message = "家庭住址至少填写一个")    List<String> homList;    public List<String> getHomList() {        return homList;    }    public void setHomList(List<String> homList) {        this.homList = homList;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    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;    }}

②第二步定义Controller,验证的参数dto属性要加@Validated,BindingResult参数中包含捕捉校验信息,程序执行过程会进入该方法体内。

@RestControllerpublic class TestValidatorController {    @RequestMapping("/testValidator")    @ResponseBody    public ValidatorDto testValidator(@Validated ValidatorDto dto, BindingResult bindingResult) {        if (bindingResult.hasErrors()) {            List<ObjectError> listObjectError = bindingResult.getAllErrors();            for (ObjectError objectError : listObjectError) {                System.out.println(objectError.getDefaultMessage());            }        }        return dto;    }}

③访问参数及System.out.println输出的校验结果:

http://localhost:8080/testValidator?name=&email=@qq.com&age=5

最小不能小于10
家庭住址至少填写一个
名字不能为空!
email格式不正确!

2、第二种校验信息在抛出的异常中获取

①第一步定义dto,所有校验都在dto的属性上进行。

public class ValidatorDto {    @NotEmpty(message = "名字不能为空!")    public String name;    @Email(message = "email格式不正确!")    public String email;    @Min(value = 10)    public int age;    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    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;    }}

②第二步定义Controller,验证的参数dto属性要加@Validated,程序不会进入该方法体内,校验信息会在抛出的异常中被捕获(我使用的是全局异常@ControllerAdvice+@ExceptionHandler捕获异常信息)。

@RestControllerpublic class TestValidatorController {    @RequestMapping("/testValidator2")    @ResponseBody    public ValidatorDto testValidator(@Validated ValidatorDto dto) {        return dto;    }}

③访问参数及校验结果:

http://localhost:8080/testValidator2?name=&email=@qq.com&age=5

3、分组校验

在不同情况下,可能对JavaBean对象的数据校验规则有所不同,有时需要根据数据状态对JavaBean中的某些属性字段进行单独验证,groups 属性将验证进行分组。

①第一步定义dto,所有校验都在dto的属性上进行。

分组一校验:name和age

分组二校验:email和age

public class ValidatorDto2 {    @NotEmpty(message = "名字不能为空!", groups = ValidatorGroup1.class)    public String name;    @Email(message = "email格式不正确!", groups = ValidatorGroup2.class)    public String email;    @Min(value = 10, groups = { ValidatorGroup1.class, ValidatorGroup2.class })    public int age;    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    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;    }}

②第二步定义分组(2个空接口类),这两空接口类,就是上面dto中的groups 分组。

public interface ValidatorGroup1 {}
public interface ValidatorGroup2 {}

③第三步定义Controller,验证的参数dto属性要加@Validated,分组的class要放到Validated中,BindingResult参数中包含捕捉校验信息,程序执行过程会进入该方法体内。

RestControllerpublic class TestValidatorController {    @RequestMapping("/testValidatorGroup1")    @ResponseBody    public ValidatorDto2 testValidatorGroup1(@Validated(ValidatorGroup1.class) ValidatorDto2 dto,            BindingResult bindingResult) {        if (bindingResult.hasErrors()) {            List<ObjectError> listObjectError = bindingResult.getAllErrors();            for (ObjectError objectError : listObjectError) {                System.out.println(objectError.getDefaultMessage());            }        }        return dto;    }    @RequestMapping("/testValidatorGroup2")    @ResponseBody    public ValidatorDto2 testValidatorGroup2(@Validated(ValidatorGroup2.class) ValidatorDto2 dto,            BindingResult bindingResult) {        if (bindingResult.hasErrors()) {            List<ObjectError> listObjectError = bindingResult.getAllErrors();            for (ObjectError objectError : listObjectError) {                System.out.println(objectError.getDefaultMessage());            }        }        return dto;    }}

④访问参数及校验结果:

分组一:

http://localhost:8080/testValidatorGroup1?name=&email=@qq.com&age=5

名字不能为空!
最小不能小于10

分组二:

http://localhost:8080/testValidatorGroup2?name=&email=@qq.com&age=5

email格式不正确!
最小不能小于10

结果说明:name校验只属于分组一,email校验只属于分组二,age校验属于分组一和分组二,跟定义的dto定义一致。

二、直接参数校验

直接参数校验就是把dto中要校验的属性当做参数放到controller的参数内,所有的校验也都放到controller中参数中,其余处理和实体类DTO校验无差异。

三、自定义校验注解

预期:做一个判断非0的注解

①定义一个注解(仿照已有的现成注解做),其中@Constraint(validatedBy = NotEqualZeroValidator.class)的NotEqualZeroValidator为自己定义的校验类

@Documented@Constraint(validatedBy = NotEqualZeroValidator.class)@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE })@Retention(RetentionPolicy.RUNTIME)public @interface NotEqualZero     String message() default "必须不等于0";    Class<?>[] groups() default { };    Class<? extends Payload>[] payload() default { };}

②定义自己的校验类,需要实现ConstraintValidator<NotEqualZero, Object>接口

public class NotEqualZeroValidator implements ConstraintValidator<NotEqualZero, Object>{    @Override    public boolean isValid(Object value, ConstraintValidatorContext context) {        return (Integer)value != 0;    }}

③使用自定义注解@NotEqualZero

public class ValidatorDto {    @NotEmpty(message = "名字不能为空!")    public String name;    @Email(message = "email格式不正确!")    public String email;    @NotEqualZero    public int age;    @NotEmpty(message = "家庭住址至少填写一个")    List<String> homeList;    public List<String> getHomeList() {        return homeList;    }    public void setHomeList(List<String> homeList) {        this.homeList = homeList;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    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;    }}

④controller

@RestControllerpublic class TestValidatorController {    @RequestMapping("/testValidator")    @ResponseBody    public ValidatorDto testValidator(@Validated ValidatorDto dto, BindingResult bindingResult) {        if (bindingResult.hasErrors()) {            List<ObjectError> listObjectError = bindingResult.getAllErrors();            for (ObjectError objectError : listObjectError) {                System.out.println(objectError.getDefaultMessage());            }        }        return dto;    }}

⑤结果

http://localhost:8080/testValidator?name=&email=@qq.com&age=0

名字不能为空!
email格式不正确!
家庭住址至少填写一个
必须不等于0

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部