spring中怎样自定义注解去校验枚举类型?

例如我有这样一个数据模型:

    @NotEmpty(message = "name can not be null.")
    @Length(min = 2, max = 20)
    private String name;

    @NotNull(message = "age can not be null")
    @Range(min = 12, max = 99, message = "age is between 12 to 99")
    private Integer age;
 
    private Gender gender;

其中Gender类定义如下:

public enum Gender {
    MALE(0),
    FEMALE(1);

    private Integer code;

    Gender(Integer code) {
        this.code = code;
    }

    @JsonValue
    public Integer getCode() {
        return code;
    }

    @JsonCreator
    public static Gender getGender(Integer code) {
        for (Gender gender : Gender.values()) {
            if (gender.getCode().equals(code)) {
                return gender;
            }
        }
        return null;
    }
}

使用spring做restful风格的开发,定义一个这样的controller

    @PostMapping(value = "enum", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseResult<EnumUser> getEnumUser(@Valid @RequestBody EnumUser enumUser, BindingResult result) {
        if (result.hasErrors()) {
            return ResponseResult.newFailedResult(1, result.getFieldError().getDefaultMessage());
        }
        return ResponseResult.newSucceedResult(enumUser);
    }

前面的两个字段nameage可以很好的被框架处理,且返回错误信息到response中去,但是枚举这个就没有想到好的办法,如果是自定义枚举校验注解的话,怎么去定义一个自定义的枚举类型的校验注解?
其实不用这种方式,直接在后面加个if else判断也就可以做判断校验的,但是感觉不优雅,如果能够做到全部由校验框架去处理的话,我们就只需要关注业务逻辑了。

阅读 10k
1 个回答

已经自己解决了,首先定义一个Gender枚举校验注解

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {GenderValidator.class})
public @interface GenderConstraint {
    String message() default "Invalid gender type";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

下面定义一个校验器,这个比较关键, 注意校验器ConstraintValidator泛型的第二个类型一定要是Enum<Gender>类型,之前一直就是这里不对所以一直报找不到ConstraintValidator

public class GenderValidator implements ConstraintValidator<GenderConstraint, Enum<Gender>> {

    @Override
    public void initialize(GenderConstraint constraintAnnotation) {
    }

    @Override
    public boolean isValid(Enum<Gender> value, ConstraintValidatorContext context) {
        if (value instanceof Gender) {
            return true;
        }
        return false;
    }
}

剩下的就是在模型里面加上注解@GenderConstraint就可以了。就跟用其它validator一样,如果校验失败则通过BindingResult来处理错误结果。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题