校验枚举类类型的入参合法性的统一方案

文章目录

  • 背景
  • 解决
  • 实践
    • 定义枚举类 InEnum注解
    • 定义验证逻辑 InEnumValidator
  • 实际使用

背景

业务要做电商平台做入参, 在电商平台被抽离成枚举类的情况下 ,要怎么验证输入的参数是正确的呢?

解决

Constraint 实现自定义验证逻辑

@Constraint 注解用于标注其他注解,将其声明为验证约束。自定义约束注解需要指定一个或多个验证器实现类。
主要属性
validatedBy(): 指定实现约束验证逻辑的类(一个或多个)。这些类必须实现 ConstraintValidator 接口
message(): 定义默认的错误消息(通常使用 {} 占位符从资源文件中获取)
groups(): 允许指定验证分组
payload(): 可以附加到约束上的额外负载信息

实践

定义枚举类 InEnum注解

用来收纳验证用的基础信息, 包含要验证的枚举类,枚举类的取值方法, 报错提示

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;@Documented
@Constraint(validatedBy = {InEnumValidator.class})
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface InEnum {// 错误提示信息String message() default "必须在指定范围 {value}";// 分组Class<?>[] groups() default {};// 负载Class<? extends Payload>[] payload() default {};// 指定枚举类Class<? extends Enum<?>> enumClass();// 枚举中用于比较的方法名(默认为name())String enumMethod() default "name";// 是否忽略大小写boolean ignoreCase() default false;// 新增:是否在错误消息中显示所有合法值boolean showValues() default true;
}

定义验证逻辑 InEnumValidator

实现 ConstraintValidator接口

  1. initialize(A constraintAnnotation) 用于初始化验证器,用来获取InEnum注解上的数据
  2. isValid(T value, ConstraintValidatorContext context) 验证逻辑 true验证通过,false验证失败, 入参context处理错误信息, value 是要验证的对象
public class InEnumValidator implements ConstraintValidator<InEnum, Object> {/*** 枚举验证器实现类,用于验证输入值是否匹配指定枚举类中的值*/private Class<? extends Enum<?>> enumClass;      // 要验证的枚举类private String enumMethod;                       // 枚举类中用于获取值的方法名private boolean ignoreCase;                      // 是否忽略大小写进行验证private boolean showValues;                      // 验证失败时是否显示所有合法值private List<String> validValues = new ArrayList<>(); // 预加载的所有合法值列表/*** 初始化验证器* @param constraintAnnotation 包含验证配置的注解实例* @throws RuntimeException 如果初始化过程中发生反射相关异常*/@Overridepublic void initialize(InEnum constraintAnnotation) {enumClass = constraintAnnotation.enumClass();enumMethod = constraintAnnotation.enumMethod();ignoreCase = constraintAnnotation.ignoreCase();showValues = constraintAnnotation.showValues();// 通过反射获取枚举值并预加载到validValues集合中try {Method method = enumClass.getMethod(enumMethod);for (Enum<?> enumConstant : enumClass.getEnumConstants()) {Object value = method.invoke(enumConstant);if (value != null) {validValues.add(value.toString());}}} catch (Exception e) {throw new RuntimeException("无法初始化枚举验证器", e);}}/*** 验证输入值是否有效* @param value 要验证的输入值* @param context 验证上下文,用于自定义错误消息* @return true如果验证通过,false如果验证失败* @throws RuntimeException 如果验证过程中发生反射相关异常*/@Overridepublic boolean isValid(Object value, ConstraintValidatorContext context) {if (value == null) {return true;}try {Method method = enumClass.getMethod(enumMethod);// 遍历枚举值进行匹配验证for (Enum<?> enumConstant : enumClass.getEnumConstants()) {Object enumValue = method.invoke(enumConstant);if (enumValue == null) {continue;}// 根据ignoreCase设置进行不同方式的比较if (ignoreCase && value instanceof String && enumValue instanceof String) {if (((String) enumValue).equalsIgnoreCase((String) value)) {return true;}} else if (Objects.equals(enumValue, value)) {return true;}}// 验证失败时处理错误消息if (showValues) {String validValuesStr = validValues.stream().collect(Collectors.joining(", "));context.disableDefaultConstraintViolation();context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate().replace("{value}", validValuesStr)).addConstraintViolation();}return false;} catch (Exception e) {throw new RuntimeException(e);}}
}

实际使用

// 1.0 定义枚举类
@Getter
@AllArgsConstructor
public enum PlatformTypeEnum {/*** 未来支持的平台很多,但是现在只支持抖音* */DY(1, "dy", "抖音"),;private final Integer value;private final String code;private final String name;public String getCode(){return code;}
}// 2.0 验证入参
@Data
public class CrowdReqVO {@NotNull(message = "抖音号不能为空")@ApiModelProperty("抖音号")private String awemeId;@DateTimeFormat(pattern = "yyyy-MM-dd")@ApiModelProperty("查询日期,格式:yyyy-MM-dd")@NotNull(message = "查询日期不能为空")private LocalDate searchDate;@ApiModelProperty("直播间类型:dy-抖音;ks-快手;sph-视频号")@NotEmpty(message = "请输入平台类型")@InEnum(enumClass = PlatformTypeEnum.class, enumMethod = "getCode", message = "平台类型必须在指定范围: {value}")private String platformType;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity-NavMesh详解-其一

今天我们来详细地探究一下Unity的NavMesh这一性能强大的组件&#xff1a; NavMesh基本使用 NavMesh简单地说本质上是一个自动寻路的AI组件&#xff0c;我们首先来学习基本的使用。 画面中我已经添加好了地面&#xff0c;目标&#xff0c;障碍物以及玩家四个要素。 注意我们要…

vue的created和mounted区别

在Vue.js中&#xff0c;created和mounted的核心区别在于调用时机和DOM可访问性‌&#xff1a;created钩子在组件实例创建后、DOM挂载前调用&#xff0c;适用于数据初始化&#xff1b;mounted钩子在DOM挂载后调用&#xff0c;支持DOM操作。‌‌ ‌调用时机与核心能力对比‌ ‌…

MySQL 8.0 OCP 英文题库解析(十四)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题121~130 试题1…

【HarmonyOS 5】拍摄美化开发实践介绍以及详细案例

以下是 HarmonyOS 5 拍摄美化功能的简洁介绍&#xff0c;整合核心能力与技术亮点&#xff1a; 一、AI 影像创新 ‌AI 魔法移图‌ 系统级图像分层技术实现人物/物体自由拖拽、缩放与复制&#xff0c;突破传统构图限制。自动分离主体与背景&#xff0c;一键生成错位创意照&…

【Java多线程从青铜到王者】懒汉模式的优化(九)

懒汉模式的问题 我们看上述的代码&#xff0c;当第一次调用getIntance的时候&#xff0c;intance为null&#xff0c;就会进入if里面&#xff0c;创建出实例&#xff0c;当不是第一次调用的时候&#xff0c;此时的intandce不是null&#xff0c;不进入循环&#xff0c;直接return…

SCI期刊查重参考文献会被查重吗?

查重的时候&#xff0c;参考文献不会被查重。 不管中文还是英文查重系统里一般都有排除参考文献的设置。 比如英文查重系统iThenticate 的排除文献的设置如下&#xff1a; 在iThenticate在线报告界面的右下角点击“漏斗”图标&#xff08;Filter&#xff09;&#xff0c; ✔…

OpenLayers 获取地图状态

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图状态信息包括中心点、当前缩放级别、比例尺以及当前鼠标移动位置信息等&#xff0c;在WebGIS开发中&#xff0c;地图状态可以方便快捷的向用户展示基…

JxBrowser 8.8.0 版本发布啦!

一次调用即可下载文件精准清除浏览数据右键点击位置检测获取元素在视口中的位置 &#x1f517; 点击此处了解更多详情。 &#x1f193; 获取 30 天免费试用。

React 中的TypeScript开发范式

在 TypeScript 中使用 React 可以提高代码的可维护性、可读性和可靠性。TypeScript 提供了静态类型检查和丰富的类型系统&#xff0c;这些功能在 React 开发中非常有用。下面详细介绍如何在 React 项目中使用 TypeScript&#xff0c;并结合泛型和 infer 来定义类型。 1. 项目初…

72道Nginx高频题整理(附答案背诵版)

1. 简述什么是Nginx &#xff1f; Nginx 是一个开源的高性能HTTP和反向代理服务器&#xff0c;也能够用作IMAP/POP3/SMTP代理服务器。它最初由Igor Sysoev为俄罗斯的一个大型网站Rambler开发&#xff0c;并在2004年首次公开发布。Nginx被设计用来解决C10k问题&#xff0c;即同…

AI时代,数据分析师如何成为不可替代的个体

在数据爆炸的 AI 时代&#xff0c;AI工具正以惊人的速度重塑数据分析行业&#xff0c;数据分析师的工作方式正在经历一场前所未有的变革。数据分析师又该如何破局&#xff0c;让自己不被AI取代呢&#xff1f; 一、AI工具对重复性工作的彻底解构 如以往我们需要花几天写一份数…

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…

Kafka入门-Broker以及文件存储机制

Kafka Broker Broker实际上就是kafka实例&#xff0c;每一个节点都是独立的Kafka服务器。 Zookeeper中存储的Kafka信息 节点的服役以及退役 服役 首先要重新建立一台全新的服务器105&#xff0c;并且在服务器中安装JDK、Zookeeper、以及Kafka。配置好基础的信息之后&#x…

dexcap升级版之DexWild——面向户外环境的灵巧手交互策略:人类和机器人演示协同训练(人类直接带上动捕手套采集数据)

前言 截止到25年6.6日&#xff0c;在没动我司『七月在线』南京、武汉团队的机器的前提下&#xff0c;长沙这边所需的前几个开发设备都已到齐——机械臂、宇树g1 edu、VR、吊架 ​长沙团队必须尽快追上南京步伐 加速前进 如上篇文章所说的&#xff0c; 为尽快 让近期新招的新同…

【基于阿里云搭建数据仓库(离线)】使用UDTF时出现报错“FlatEventUDTF cannot be resolved”

目录 问题&#xff1a; 可能的原因有&#xff1a; 解决方法&#xff1a; 问题&#xff1a; 已经将包含第三方依赖的jar包上传到dataworks&#xff0c;并且成功注册函数&#xff0c;但是还是报错&#xff1a;“FlatEventUDTF cannot be resolved”&#xff0c;如下&#xff1a…

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +

【LC实战派】小智固件编译

这篇写给立创吴总&#xff0c;是节前答应他配合git代码的说明&#xff1b;也给所有对小智感兴趣的小伙伴。 请多提意见&#xff0c;让这份文档更有价值 - 第一当然是拉取源码 - git clone https://github.com/78/xiaozhi-esp32.git 完成后&#xff0c;先查看固件中实际的…

有没有 MariaDB 5.5.56 对应 MySQL CONNECTION_CONTROL 插件

有没有 MariaDB 对应 MySQL CONNECTION_CONTROL 插件 背景 写这篇文章的目的是因为昨晚半夜突然被call起来&#xff0c;有一套系统的mysql数据库启动失败了。尝试了重启服务器也不行。让我协助排查一下问题出在哪。 分析过程 一开始拿到服务器IP地址&#xff0c;就去数据库…

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…