SpringBoot 参数校验踩坑总结(附:Service层参数校验标准示例)

1,530 阅读2分钟

SpringBoot的参数校验

1、常用注解@Valid @Valided

  • 区别
    • Valid JDK的原生注解,可以用在方法构造函数方法参数成员属性

    @Valid用在成员属性(field)上实现对成员对象的嵌套校验

    class DateInfo {
        @NotBlank
        private String id;
        //可以让person成员属性也得到了校验
        @Valid
        private Person person;
    }
    class Person{
        @NotBlank
        private String name;
    }
    
    • Valided 可以理解为Spring对 @Valid 的封装扩展。 用在类型方法方法参数上。

    不能用于成员属性,但是支持分组

  • 相同点

    都只能对Object的属性进行校验,不能对单个的参数进行校验

    //无效
    @GetMapping("/testValid")
    public String getOne(@Valid @Min(20) int a) {
        System.out.println(a);
        return a + "testValid";
    }
    //无效
    @GetMapping("/testValidated")
    public String getTwo(@Validated @Min(20) int a) {
        System.out.println(a);
        return a + "testValidated";
    }
    class Mode {
        @Min(value = 20, message = "最小为20")
        int a;
    }
    //有效
    @GetMapping("/testValidModel")
    public String getTwo(@Valid Mode mode) {
        System.out.println(mode.a);
        return mode.a + "testValidModel";
    }
    
    
  • 关于上述共同点(对单个参数的校验失效)解决
    • 在该方法所在类上添加 @Validated 注解

2、Service层的参数校验

  • 标准做法
    • 接口方法对参数添加 @Valid 注解(如果有分组,需要在接口方法上再添加 @Valided({group.class}) 注解
    • 实现类上添加 @Valided 注解
    //待校验实体
    @Data
    public class TaskHealthReq extends QRotBaseRequest {
        @NotBlank
        @Pattern(regexp = Constant.Regex.ADDRESS,message = "地址有误",groups = {ValidationGroup.TASK_HEALTH_INSERT.class})
        private String address;
    }
    
    //分组
    public interface ValidationGroup {
        interface TASK_HEALTH_INSERT extends Default {}
    }
    
    //接口
    public interface TaskHealthService {
        @Validated({ValidationGroup.TASK_HEALTH_INSERT.class})
        boolean insertHealthTask(@Valid @NotNull TaskHealthReq req);
    }
    
    //实现类
    @Service
    @Slf4j
    @Validated
    public class TaskHealthServiceImpl implements TaskHealthService{
        @Override
        public boolean insertHealthTask(TaskHealthReq req){
            //***
        }
    } 
    

总结

  • 注意 @Valid@Valided在Controller层只能使用在Object对象上生效。如果需要在单个参数生效需要在对应类上添加 @Valided 注解
  • Service层 @Valid 的使用注意规范(尤其注意分组情况下的使用)
  • 关于对各个对象属性的具体规则注解使用注意一下几个的区别
    • @Empty和@Blank
    • @Min 和@DecimalMin