SpringBoot EnumValidator验证器实现
实现背景
在实际开发过程中,往往也需要对某些参数进行枚举合法值校验。如果在代码中大量充斥者if else check代码,实现不够优雅。借鉴Hibernate其他优秀验证器的实现,Enum校验也可以拥有自己的验证器!
实现原理
1. 定义枚举检查注解@EnumCheck,方便在请求对象参数上使用;
2. 定义接口EnumValidator,让需要验证的Enum类实现getValue()方法,主要目的是获取枚举的比较值;
3. 实现接口ConstraintValidator的isValid()方法,实现具体的枚举校验逻辑。
代码实现
1. @EnumCheck注解类:
/** * 枚举检查注解 * * @author binglang * @date 2021/8/31 11:41 */ @Documented @Constraint(validatedBy = EnumConstraintValidator.class) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Repeatable(EnumCheck.List.class) public @interface EnumCheck { /** * 提示信息 * */ String message() default "{javax.validation.constraints.EnumCheck.message}"; /** * 分组 * */ Class<?>[] groups() default { }; /** * 扩展对象 * */ Class<? extends Payload>[] payload() default { }; /** * 必须实现EnumValidator接口的枚举类 * */ Class<? extends EnumValidator> clazz(); /** * 调用的方法名称 */ String method() default "getValue"; /** * Defines several {@code @In} constraints on the same element. * * @see EnumCheck */ @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Documented @interface List { /** * In数组 */ EnumCheck[] value(); } }
2. EnumValidator接口定义:
/** * 枚举验证接口 * * @author binglang * @date 2021/8/31 11:43 */ public interface EnumValidator { Object getValue(); }
3. EnumConstraintValidator验证器具体实现:
/** * 枚举验证器实现 * * @author binglang * @date 2021/8/31 11:44 */ public class EnumConstraintValidator implements ConstraintValidator<EnumCheck, Object> { /** * 注解对象 */ private EnumCheck annotation; /** * 初始化方法 * * @param constraintAnnotation 注解对象 */ @Override public void initialize(EnumCheck constraintAnnotation) { this.annotation = constraintAnnotation; } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { if (Objects.isNull(value)) { return false; } Object[] enumConstants = annotation.clazz().getEnumConstants(); try { // 核心代码实现 Method method = annotation.clazz().getMethod(annotation.method()); for (Object enumConstant : enumConstants) { if (value.equals(method.invoke(enumConstant))) { return true; } } } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } return false; } }
如何使用
1. 需要校验的枚举类实现上面的EnumValidator接口:
/** * 引用节点类型 * * @author binglang * @date 2021/7/13 20:12 */ public enum RefNodeType implements EnumValidator { FIELD("field", "field"), FUNC("func", "func"); private final String code; private final String label; RefNodeType(String code, String label) { this.code = code; this.label = label; } public String getCode() { return code; } public String getLabel() { return label; } // 实现getValue()逻辑 @Override public Object getValue() { return code; }
2. 请求对象使用@EnumCheck注解:
@Data public class TestDto { @ApiModelProperty(value = "变量类型") @NotBlank(message = "变量类型不能为空") @EnumCheck(clazz = RefNodeType.class, message = "变量类型不合法") private String refNodeType; }
分类:
Java技术
, SpringBoot
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
2018-11-30 javascript之url转义escape()、encodeURI()和decodeURI()
2018-11-30 yii2.0安装ElasticSearch及使用
2018-11-30 Linux 查看CPU、Memory等资源占用情况