@Valid使用详解以及自定义注解的简单使用

@Valid注解用于校验

一.@Valid注解的基本使用:

步骤1:将@Valid注解直接加在变量user之前,并且传入BindingResult对象(也可不传入),用于获取校验失败情况下的反馈信息,如下代码

@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping
    public User create (@Valid @RequestBody User user, BindingResult bindingResult) {
	    if(bindingResult.hasErrors()){
            System.out.println(bindingResult.getFieldError().getDefaultMessage());
            return null;
        }
        System.out.println(user.getId());
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        user.setId("1");
        return user;
    }
} 

步骤2:然后在 User 类中添加验证信息的要求

@Data
public class User {
    private String id;  
    private String username;
    @NotBlank(message = "密码不能为空")
    private String password;
}

@NotBlank 注解所指的 password 字段,表示验证密码不能为空,如果为空的话,上面 Controller 中的 create 方法会将message 中的"密码不能为空"返回。

二.数据验证的规则

@Entity :表明是一个实体类
@Table(name="xxx")不加name默认是类名小写
@Id 主键注解
@GeneratedValue()主键生成策略
@Column(name="xxx" nullable=false) 列名对应数据表的一列 name默认是属性名 nullable是值不能为空默认是true
@Data 等价于@Getter + @Setter 即不用写get,set, tostring等方法
@Basic  用于没有任何标注的 getXxx() 方法,默认即为 @Basic,所以若一个 getter 方法无任何注解,可以使用 @Basic 注解,也可以不使用
@NotEmpty 用在集合上面(不能注释枚举) 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) 加了@NotEmpty的String类、Collection、Map、数组,是不能为null或者长度为0的
@NotBlank 用在String上面 验证注解的元素值不为空 不能为null且trim()之后size>0
@NotNull 用在所有类型上面  被注释的元素不能为null   用在基本类型上,如Integer、Double。用在集合数组时,不能为null,但可以为empty,没有Size的约束(size = 0)
​@Null 被注释的元素必须为null
@AssertTrue 被注释的元素必须为true
@AssertFalse 被注释的元素必须为false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max,min) 被注释的元素的大小必须在指定的范围内。值必须是String、 集合或数组, 并且它的长度要符合给定的范围
@Digits(integer,fraction) 被注释的元素必须是一个小数,且整数部分位数不能超过integer,小数部分位数不能超过fraction
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式。
@Email 被注释的元素必须是电子邮件地址 也可以通过正则表达式和flag指定自定义的email格式
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串必须非空 @Range 被注释的元素必须在合适的范围内
@Range(min=,max=) 数字必须大于等于min,小于等于max
@SafeHtml  字符串是安全的html
@URL 字符串是安全的URL

三.自定义注解的使用

具体问题描述:在校验过程中,需要限制该属性只能传入规定内容,于是使用枚举类进行约束参数。

@Getter
public enum RoleEnum implements CodeEnum {
    BUYER(1, "顾客"),
    SELLER(2, "商家"),
    RIDER(3, "骑手"),
    ;
    Integer code;  
    String message;
    RoleEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

然后可在controller中进行参数校验,但由于项目中该类校验较多,造成代码冗余。故采用自定义注解进行校验

	@Data
	public class UserInfo {
	    @EnumValidator(value = RoleEnum.class)
	    private Integer role = RoleEnum.BUYER.getCode();
	}

注解的具体内容:

@Target({ElementType.METHOD, ElementType.FIELD}) //在方法和属性上面起作用
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidatorClass.class)
public @interface EnumValidator {
    Class value();
    String message() default "The input parameter value is not in the correct enumeration";
    Class[] groups() default { };
    Class[] payload() default { };
}

下面是校验器:

@Slf4j
public class EnumValidatorClass implements ConstraintValidator {

    private List values = new ArrayList<>();

    @Override
    public void initialize(EnumValidator enumValidator) {
        Class clz = enumValidator.value();
        Object[] objects = clz.getEnumConstants();
        try {
            Method method = clz.getMethod("getCode");
            if (Objects.isNull(method)) {
                throw new Exception(String.format("枚举对象{}缺少字段名为code的字段", clz.getName()));
            }
            Object value = null;
            for (Object obj : objects) {
                value = method.invoke(obj);
                values.add(value);
            }
        } catch (Exception e) {
            log.error("[处理枚举校验异常]", e);
        }
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        return Objects.isNull(value) || values.contains(value);
    }
}
 
  

后续遇到此类相似需求,只需创建enum类,并在对应属性上添加注解即可。当然,自定义注解能解决的问题还有很多,这就需要根据不同需求进行思考调整,希望大家都能掌握自定义注解的使用。

你可能感兴趣的:(java后端开发,java)