文章目录
- SpringBoot中@Validated或@Valid注解校验的使用
- 1. 添加依赖
- 2. 使用示例准备
- 2-1 测试示例用到的类
- 2-2 实体Dto,加入校验注解
- 2-2 Controller
- 3. 示例测试
- 4. @Valid 和 @Validated注解详解
- 4-1 常用规则注解
- 4-2 分组验证
- 4-2-1 示例准备
- 4-2-2 Controller接口
- 4-2-3 PostMan测试
- 4-3 嵌套校验
- 4-3-1 示例【复杂对象嵌套校验】
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);
}