spring boot mvc Validator 自定义校验(枚举值校验)

目录

  • 概述
  • 案例需求分析
  • 案例自定义校验实现
  • 案例业务对象使用

概述

spring mvc 工程中,后端接收前端传入的对象时,需要对对象中的属性做合法性校验,避免业务数据出现脏数据, spring 自身有多重校验方式,本文基于java bean校验方式进行阐述, spring java bean 校验依赖于hibernate validator, 详细校验属性参考官网: https://hibernate.org/validator/

本文框架版本:

spring boot: 2.3.5.RELEASE

案例需求分析

开发项目中,经常会使用到枚举,前端传入到后端时,需要知道对应的值,是否在枚举范围内,如果没在枚举范围内,则提示异常信息

异常抛给前端的格式自定义,本人使用的spring 自定义异常,将此异常捕获后,包装成前端可解析的格式

案例自定义校验实现

自定义注解:EnumValid

@Constraint(validatedBy = {EnumValidator.class})
@Target({ElementType.FIELD, TYPE_USE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumValid {

    String message();

    Class[] groups() default {};

    Classextends Payload>[] payload() default {};

    Class target();

    String field() default "name";
}

校验器实现: EnumValidator

public class EnumValidator implements ConstraintValidator {

    /** 枚举需要校验的属性名**/
    private static final String DEFAULT_FIELD = "code";
    /** 枚举类 */
    private Class            clazz;
    /** 比较的属性 */
    private String              field;

    @Override
    public void initialize(EnumValid constraintAnnotation) {
        this.clazz = constraintAnnotation.target();
        this.field = constraintAnnotation.field();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (null == value) {
            return true;
        }

        if (!clazz.isEnum()) {
            return false;
        }

        Object[] enumOptions = clazz.getEnumConstants();
        try {
            Method method;
            if (StringUtils.equals(field, DEFAULT_FIELD)) {
                method = clazz.getMethod(field);
            } else {
                String getMethodName = "get" + upperCaseFirstChar(this.field);
                method = clazz.getMethod(getMethodName);
            }

            for (Object obj : enumOptions) {
                Object code = method.invoke(obj, null);
                if (StringUtils.equals(value.toString(), code.toString())) {
                    return true;
                }
            }
        } catch (Exception e) {
            return false;
        }

        return false;
    }

    private static String upperCaseFirstChar(String str) {
        char[] cs = str.toCharArray();
        cs[0] -= 32;
        return String.valueOf(cs);
    }

}

案例业务对象使用

Note: 案例中使用了lombok,如未使用,则自行生成get以及构造方法; cotroller 以及实现类这里就不再赘述

枚举类: SexEnum

@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum SexEnum {
    YEAR(1, "年"),
    SELF_YEAR(10, "半年"),
    QUARTER(20, "季度"),
    MONTH(30, "月");

    private Integer code;
    private String desc;

}

接收前端的对象类: UserVo ,此对象中@EnumValid为自定义校验注解

@Data
public class RatingLevelTaskVo implements Serializable {


    @NotBlank(message = "用户名称不可为空")
    private String userName;

    @NotNull(message = "用户性别不可为空")
    @EnumValid(target = SexEnum.class, field = "code", message = "用户性别不允许非法值")
    private Integer sex;

}

你可能感兴趣的:(java,spring,spring,boot,javabean,vue)