Spring Boot如何以优雅的姿势校验参数

1. 引入jar包


    javax.validation
    validation-api

2. 常用注解

注解 注解解释
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@NotEmpty 被注释的字符串的必须非空
@NotBlank 验证字符串非null,且长度必须大于0
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
@Email 被注释的元素必须是电子邮箱地址
@Negative 被注释的元素必须小于0
@Positive 被注释的元素必须大于0

3. 示例

首先在DTO中对需要校验的参数添加注解

@Data
public class UserDTO {
    @NotBlank(message = "用户名不能为空")
    private String userName;
    @Email(message = "邮箱格式不正确")
    private String email;
    @Negative(message = "年龄只能为正整数")
    private Integer age;
    @NotNull(message = "性别不能为空")
    private Integer sex;
    @NotNull(message = "类型不能为空")
    @Max(value = 2,message = "类型只能是两位数")
    @Min(value = 1,message = "类型只能是两位数")
    private Integer type;
}

然后需要在controller方法体添加@Validated不加@Validated校验会不起作用

@PostMapping("/v1/add_user")
    public ResultMsg addUser(@RequestBody @Validated UserDTO dto){
    try {
        return ResultMsg.success(userService.userRealName(dto));
    } catch (UserException se){
        return ResultMsg.failure(se.getMessage());
    }
}

4. 全局统一返回格式

@ExceptionHandler(Exception.class)
@ResponseBody
public ResultMsg globalException(Exception e) {
    log.warn(e.getMessage(), e);
    if (e instanceof MethodArgumentNotValidException){
        return ResultMsg.failure(((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage());
    }
    return ResultMsg.failure(e.getMessage());
}

5. 自定义注解
上面的注解只有这么多,如果有特殊校验的参数我们可以使用Validator自定义注解进行校验。下面我们自定义一个身份证号码校验

  • 创建一个IdCard注解类
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdCardValidator.class)
public @interface IdCard {
    String message() default "身份证号码不合法";

    Class[] groups() default {};//分组

    Class[] payload() default {};// 针对于Bean
}
  • 添加IdCardValidator 主要进行验证逻辑
public class IdCardValidator implements ConstraintValidator {
    @Override
    public void initialize(IdCard constraintAnnotation) {
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null)
            return false;
        return UserIdentityUtil.isIdCard(value.toString());
    }
}

6. 分组
就比如上面我们定义的UserDTO中的参数如果要复用的话怎么办,重新定义一个觉得比较麻烦,但是Validator提供了分组方法完美了解决DTO复用问题,
现在我们注册的接口修改一下规则,只有用户名不能为空其他参数都不进行校验
首先先创建分组的接口

public interface Create  extends Default {
}

修改UserDTO

@Data
public class UserDTO {
    @NotBlank(message = "用户名不能为空",groups = Create.class)
    private String userName;
    @Email(message = "邮箱格式不正确",groups = Update.class)
    private String email;
    @Negative(message = "年龄只能为正整数",groups = Update.class)
    private Integer age;
    @NotNull(message = "性别不能为空",groups = Update.class)
    private Integer sex;
}

然后在修改Controller在@Validated中传入Create.class

@PostMapping("/v1/add_user")
public ResultMsg addUser(@Validated(Create.class) UserDTO dto){
    try {
        return ResultMsg.success(userService.userRealName(dto));
    } catch (UserException se){
        return ResultMsg.failure(se.getMessage());
    }
}

你可能感兴趣的:(java,spring,springboot)