SpringBoot中@Validated或@Valid注解校验的使用

发布于:2024-11-02 ⋅ 阅读:(41) ⋅ 点赞:(0)

SpringBoot中@Validated或@Valid注解校验的使用

1. 添加依赖

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

2. 使用示例准备

2-1 测试示例用到的类

@AllArgsConstructor
@Data
public class ResponseDto<T> {
    private int code;
    private String message;
    private T data;
}
public class ResponseUtil {
    public static  <T> ResponseDto success(T data){
        return new ResponseDto(200,"success",data);
    }
    public static <T> ResponseDto fail(T data){
        return new ResponseDto(1,"fail",data);
    }
}
/**
 * 全局异常处理类
 */
@Slf4j
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    private ResponseDto handlerParameterCheckException(Exception e) {
        return ResponseUtil.fail(e.toString());
    }

}

2-2 实体Dto,加入校验注解

// @NotNull表示参数不能为空
// @Min表示数值的最小值
// @Max表示数值的最大值
// message属性用来设置验证失败的提示信息
@Data
public class UserInfoDto {
    @NotNull(message = "用户姓名不能为空")
    private String userName;
    @NotNull(message = "年龄不能为空")
    @Min(value = 18,message = "年龄不能小于18")
    @Max(value = 100,message = "年龄不能超过100")
    private Integer age;
}

2-2 Controller

@RestController
@RequestMapping("/Api/v1.0")
public class Demo1Controller {

    @PostMapping("/user")
    public ResponseDto validUserInfo(@Validated @RequestBody UserInfoDto param){
        return ResponseUtil.success(param);
    }
}

3. 示例测试

使用PostMan发起请求
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. @Valid 和 @Validated注解详解

4-1 常用规则注解

下面表格列出常用校验类及主要功能。
这些注解必须配合@Valid或@Validated使用,通过这两个注解开启校验

在这里插入图片描述
在这里插入图片描述

注 :
对于长度的校验基本都支持字符串、集合、Map、数组的长度。
下面是@Valid和@Validated的区别。

在这里插入图片描述

// 注 :嵌套验证。
//	JavaBean A中某个属性, 其类型是JavaBean B,对A进行验证的同时验证B。

相同点:

  • @Valid 和 @Validated 两者都可以对数据进行校验,在校验字段上加上规则注解(@NotNull,
    @NotEmpty等)都可以对 @Valid 和 @Validated 生效。
  • @Valid 和 @Validated 两者都可以与BindingResult bindingResult配对出现,
    并且形参顺序是固定的(一前一后),controller对BindingResult处理返回校验提示。
  • @Valid 和 @Validated 两者也可以单独使用,单独使用当校验不通过时会抛出
    BindException异常。这时需要再写一个全局校验异常捕获处理类,然后返回校验提示。

不同点

  • @Valid可以用在方法、构造函数、方法参数和成员属性(field)上;
  • @Valid可以进行嵌套校验,但是,需要在嵌套的字段上面加上@Valid注解; @Valid不支持分组。
  • @Validated可以用在方法、构造函数、方法参数;但是不能用在成员属性(字段)上;
  • @Validated不支持嵌套校验,因为不能用在成员属性(字段)上;
  • @Validated支持分组验证,以在入参验证时,根据不同的分组采用不同的验证机制;

4-2 分组验证

4-2-1 示例准备
/**
 * 成年人
 */
public interface Adult {
}

/**
 * 未成年人
 */
public interface Juveniles {
}
//	提示
//		主要的修改是在校验注解中添加了groups属性,用来指定当前的校验针对哪一个组。
//		@Max(value = 100,message = "年龄不能超过100",groups = Adult.class)和
//		@Min(value = 18,message = "年龄不能小于18",groups = Adult.class)
//			指定了成年人用户信息的年龄属性验证规则。
//		@Max(value = 17,message = "年龄不能大于17岁",groups = Juveniles.class)
//			指定了未成年人用户信息的年龄要小于18岁。

@Data
public class UserInfoDTO {
    @NotNull(message = "用户姓名不能为空")
    private String userName;
    @NotNull(message = "年龄不能为空")
    @Min(value = 18,message = "年龄不能小于18",groups = Adult.class)
    @Max(value = 100,message = "年龄不能超过100",groups = Adult.class)
    @Max(value = 17,message = "年龄不能大于17岁",groups = Juveniles.class)
    private Integer age;
}
4-2-2 Controller接口
/**
 * 成年人  --> @Validated(value = Adult.class):仅校验成年人,即有groups = Adult.class的属性
 * @param param
 * @return
 */
@PostMapping("/userAdult")
public UserInfoDTO validUserAdult(@Validated(value = Adult.class) @RequestBody UserInfoDTO param){
    return param;
}

/**
 * 未成年人    --> @Validated(value = Adult.class):仅校验未成年人,即有groups = Juveniles.class的属性
 * @param param
 * @return
 */
@PostMapping("/userJuveniles")
public UserInfoDTO validUserJuveniles(@Validated(value = Juveniles.class) @RequestBody UserInfoDTO param){
    return param;
}
4-2-3 PostMan测试

在这里插入图片描述
在这里插入图片描述

4-3 嵌套校验

//	1. @Validated无法单独提供嵌套验证功能。
//		不能用在成员属性上,
//		能配合嵌套验证注解@Valid进行嵌套验证
//	2. 在嵌套对象字段上加上@Valid注解,如:
public class User {
    @Valid
    private Address address;
}

4-3-1 示例【复杂对象嵌套校验】
@Data
public class Object1 {
    @Length(max = 50,message = "长度不能超过50位字符")
    @NotBlank(message = "名称不能为空")
    private String name;
    @NotNull(message = "不能为空")
    private Integer grade;
    @NotNull(message = "计分展示不能为空")
    private Integer scoreDimension;
    @NotNull(message = "obj2s不能为空")

	/**
     * 嵌套验证时必须使用 @Valid注解
     */
    @Valid
    private List<Object2> obj2s;
}


@Data
public class Object2{
    @Length(max = 50, message = "长度不能超过50位字符")
    @NotBlank(message = "分类名称不能为空")
    private String categoryName;

	/**
     * 嵌套验证时必须使用 @Valid注解
     */
    @Valid
    private List<Object3> obj3s;
}

@Data
public class Object3{
    @NotNull(message = "分值不能为空")
    @Max(value =1000 , message = "分值最大不能超过1000")
    private Integer score;
    @Size(max = 500, message = "最多可输入500个字符")
    private String standards;

    @Size(max = 10, message = "标最多10条")
    private String[] urls;

    @NotNull(message = "不能为空")
    private Integer[] rating;
}

//controller校验
    @PostMapping("/check")
    public Result<Void> check( @Validated @RequestBody Object1 obj1) {
        return servei1.check(obj1);
    }

网站公告

今日签到

点亮在社区的每一天
去签到