自定义javax.validation校验枚举类
枚举类单一情况
package com.archermind.cloud.phone.dto.portal.external.validation.validator;import com.archermind.cloud.phone.dto.portal.external.validation.constraints.EnumValidation;
import lombok.extern.slf4j.Slf4j;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Method;/*** 枚举类型校验类** @author cyc* @version 2022/10/18 0018* @see [相关类/方法]* @since [cloud-phone-baseline]*/
@Slf4j
public class EnumValidator implements ConstraintValidator<EnumValidation, Object>
{private EnumValidation annotation;/*** Initializes the validator in preparation for* {@link #isValid(Object, ConstraintValidatorContext)} calls.* The constraint annotation for a given constraint declaration* is passed.* <p>* This method is guaranteed to be called before any use of this instance for* validation.* <p>* The default implementation is a no-op.** @param constraintAnnotation annotation instance for a given constraint declaration*/@Overridepublic void initialize (EnumValidation constraintAnnotation){this.annotation = constraintAnnotation;}/*** Implements the validation logic.* The state of {@code value} must not be altered.* <p>* This method can be accessed concurrently, thread-safety must be ensured* by the implementation.** @param value object to validate* @param context context in which the constraint is evaluated* @return {@code false} if {@code value} does not pass the constraint*/@Overridepublic boolean isValid (Object value, ConstraintValidatorContext context){if (value == null){return annotation.optional ();}Object[] objects = annotation.enumClass ().getEnumConstants ();try{Method method = annotation.enumClass ().getMethod (annotation.method ());for (Object o : objects){if (value.equals (method.invoke (o))){return true;}}}catch (Exception e){log.info ("EnumValidator catch en exception: ", e);return false;}return false;}
}
EnumValidation
package com.archermind.cloud.phone.dto.portal.external.validation.constraints;import com.archermind.cloud.phone.dto.portal.external.validation.validator.EnumValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** 枚举类校验注解,用于接口参数校验使用* 可用于对象字段** @author cyc* @version 2022/10/18 0018* @see [自定义注解]* @since [cloud-phone-baseline]*/
@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention (RUNTIME)
@Documented
@Repeatable (EnumValidation.List.class)
@Constraint (validatedBy = { EnumValidator.class })
public @interface EnumValidation
{String message () default "Invalid enum value";Class<?> enumClass ();Class<?>[] groups () default {};Class<? extends Payload>[] payload () default {};String method () default "getType";boolean optional () default false;/*** Defines several {@link EnumValidation} annotations on the same element.** @see EnumValidation*/@Documented@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention (RUNTIME)@interface List{EnumValidation[] value ();}
}
使用
/*** <一句话功能简述> <功能详细描述>** @author cyc* @version 2023/3/8* @see [相关类/方法]* @since [Operator.java]*/
@Slf4j
@AllArgsConstructor
@Getter
public enum ProductTypeEnum
{//续费续约类型CPH ("CPH", "云手机"),STB ("STB", "云魔百盒");private final String type;private final String message;
}
使用类
@Data
public class ProductCreateReq implements Serializable
{
/*** 产品类型(Y)* CPH:云手机* STB:云魔百盒*/@NotBlank (message = "产品类型不能为空")@EnumValidation (enumClass = ProductTypeEnum.class, optional = true, message = "产品类型枚举类不正确")private String type;
}
当前端传递过来多个类型:例如:aa;bb
package com.archermind.cloud.phone.dto.portal.external.validation.constraints;import com.archermind.cloud.phone.dto.portal.external.validation.validator.StringEnumValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** 枚举类校验注解,用于接口参数校验使用* 可用于对象字段** @author cyc* @version 2022/10/18 0018* @see [自定义注解]* @since [cloud-phone-baseline]*/
@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention (RUNTIME)
@Documented
@Repeatable (StringEnumValidation.List.class)
@Constraint (validatedBy = { StringEnumValidator.class })
public @interface StringEnumValidation
{String message () default "Invalid enum value";Class<?> enumClass ();Class<?>[] groups () default {};Class<? extends Payload>[] payload () default {};String method () default "getType";boolean optional () default false;/*** Defines several {@link StringEnumValidation} annotations on the same element.** @see StringEnumValidation*/@Documented@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention (RUNTIME)@interface List{StringEnumValidation[] value ();}
}
StringEnumValidator
package com.archermind.cloud.phone.dto.portal.external.validation.validator;import com.archermind.cloud.phone.dto.portal.external.validation.constraints.StringEnumValidation;
import lombok.extern.slf4j.Slf4j;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.List;/*** 枚举类型校验类** @author cyc* @version 2022/10/18 0018* @see [相关类/方法]* @since [cloud-phone-baseline]*/
@Slf4j
public class StringEnumValidator implements ConstraintValidator<StringEnumValidation, String>
{private StringEnumValidation annotation;/*** Initializes the validator in preparation for* {@link #isValid(String, ConstraintValidatorContext)} calls.* The constraint annotation for a given constraint declaration* is passed.* <p>* This method is guaranteed to be called before any use of this instance for* validation.* <p>* The default implementation is a no-op.** @param constraintAnnotation annotation instance for a given constraint declaration*/@Overridepublic void initialize (StringEnumValidation constraintAnnotation){this.annotation = constraintAnnotation;}/*** Implements the validation logic.* The state of {@code value} must not be altered.* <p>* This method can be accessed concurrently, thread-safety must be ensured* by the implementation.** @param value object to validate* @param context context in which the constraint is evaluated* @return {@code false} if {@code value} does not pass the constraint*/@Overridepublic boolean isValid (String value, ConstraintValidatorContext context){if (value == null || value.equals ("")){return annotation.optional ();}Object[] objects = annotation.enumClass ().getEnumConstants ();List<String> dest = new ArrayList<> ();for (Object object : objects){dest.add (object.toString ());}try{String[] split = value.split (";");for (String s : split){if (! dest.contains (s)){return false;}}}catch (Exception e){log.info ("EnumValidator catch en exception: ", e);return false;}return true;}
}
使用
/*** 购买类型** @author cyc* @version 2023/3/9* @see [相关类/方法]* @since [Operator.java]*/
@Slf4j
@AllArgsConstructor
@Getter
public enum ProductItemOrderTypeEnum
{TRY ("TRY", "试用"),RENEW ("RENEW", "续费"),EXCHANGE_BUY ("EXCHANGE_BUY", "兑换购买"),EXCHANGE_RENEW ("EXCHANGE_RENEW", "利用兑换码续订"),BUY ("BUY", "购买");private final String type;private final String message;
}
@Data
public class ProductItemCreateReq implements Serializable
{
/*** 购买类型* TRY:试用* BUY:购买* RENEW:续费* EXCHANGE_BUY:兑换购买* EXCHANGE_RENEW:利用兑换码续订* (可以多选,用英文分号分隔,例如:BUY;RENEW)* 为空则表示不限制*/@StringEnumValidation (enumClass = ProductItemOrderTypeEnum.class, optional = true, message = "购买类型枚举类不正确")private String orderType;
}
相关文章:
自定义javax.validation校验枚举类
枚举类单一情况 package com.archermind.cloud.phone.dto.portal.external.validation.validator;import com.archermind.cloud.phone.dto.portal.external.validation.constraints.EnumValidation; import lombok.extern.slf4j.Slf4j;import javax.validation.ConstraintVali…...

[Java·算法·中等]LeetCode39. 组合总和
每天一题,防止痴呆题目示例分析思路1题解1分析思路2题解2👉️ 力扣原文 题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形…...

【Linux】vi和vim编辑器
目录主题主题 三种常见模式: 正常模式 以vim 打开一个档案就直接进入一般模式了(这是默认的模式)。在这个模式中,你可以使用[上下左右]按键来移动光标,你可以使用『删除字符』或『删除整行』来处理档案内容,也可以使用「复制、…...

BIO,NIO,AIO
IO模型 用什么样的通道进行数据传输和接收,java支持3种io网络编程模式 BIO NIO AIO BIO 同步阻塞 一个客户端连接对应一个处理线程 BIO示例代码(客户端和服务端) package com.tuling.bio;import java.io.IOException; import java.net.So…...
代码随想录刷题-数组-有序数组的平方
文章目录有序数组的平方习题暴力排序双指针有序数组的平方 本节对应代码随想录中:代码随想录,讲解视频:有序数组的平方_哔哩哔哩_bilibili 习题 题目链接:977. 有序数组的平方 - 力扣(LeetCode) 给你一…...

【玩转c++】stack和queue的介绍和模拟实现
本期主题:list的讲解和模拟实现博客主页: 小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限,出现错误希望大家不吝赐stack的介绍和使用1.1.stack的介绍1. stack是一种容器适配器,专门用在具有后进先出操作的上…...

Linux order(文件、磁盘、网络、系统管理、备份压缩)
1. Linux 文件命令 -rwxrwxrwx chmod:change mode,用于(文件所有者或 root )变更用户(u:owner g:group o:other a:all)的权限 chmod [OPTION]… MODE[,MODE]… FILE… OPTION -R:递归修改more option:chmod…...

最详细的CentOS7安装Mysql数据库服务
1.查看是否安装mysql: rpm -qa | grep mysql如果有查出来东西,使用命令删除: rpm -e xxx2.检查是否有mysql用户组和mysql用户,没有就添加有就忽略: groups mysql 添加用户组和用户 groupadd mysql && useradd -r -g mysql mysql&a…...

【IoT】项目管理:如何做好端到端的项目管理?
今天主要来谈谈项目管理这个话题。 首先来看一个我在网络上看到的一个关于项目管理的案例或者是段子。 将项目管理的作用及意义非常直观地展示了出来。 有一个植树搞绿化的企业,在公司内部设置有五个部门,分别是: 运输部门;挖坑部…...

渲染十万条数据就把你难住了?不存在的!
虚拟列表的使用场景如果我想要在网页中放大量的列表项,纯渲染的话,对于浏览器性能将会是个极大的挑战,会造成滚动卡顿,整体体验非常不好,主要有以下问题:页面等待时间极长,用户体验差CPU计算能力…...
编程学习的心路历程和困惑回顾
回首入行9年的经历,从大一开始学习C语言和数据结构,老师一直是在用IDE演示程序的编写和运行,我们也就一直在跟黑乎乎的命令行窗口打交道。 后来在一些课程的实验环节,接触到了一些别人编写好的工程代码,知道了Makefile…...

请介绍类加载过程,什么是双亲委派模型?
第23讲 | 请介绍类加载过程,什么是双亲委派模型? Java 通过引入字节码和 JVM 机制,提供了强大的跨平台能力,理解 Java 的类加载机制是深入 Java 开发的必要条件,也是个面试考察热点。 今天我要问你的问题是࿰…...

Navisworks编辑材质和Revit快速切换材质问题
一、如何在Navisworks2016中编辑材质 初次使用NW2016-2017时发现,原来用于创建编辑材质的小地球不见了,如图1所示,在各大技术群里求助没有回应,度娘搜索也总是摇头。 经过仔细排查可能出现的地方,终于找到了可以编辑材…...

Object对象键值的输出循序到底如何排列的?
1.日常摸鱼看八股 今天又是复习八股文的一天,发现还是彻底懂得原理才好和面试官吹牛批呀。 接着来看看我chat大宝贝的回答: 在现代浏览器中,Object 对象的键值输出循序是比较稳定的,通常是按照如下顺序输出: 所有的数…...

气泡式水位计的安装方法详解
气泡水位计的安装实际上就是气管的安装,气管的安装是否正确将直接影响到仪器测量数据的结果,气泡水位计它由活塞泵产生的压缩空气流经测量管和气泡室,进入被测的水体中,测量管中的静压力与气泡室上的水位高度成正比。那么接下来就…...
求“二维随机变量的期望E(X)与方差D(X)”例题(一)
离散型 设随机变量(X,Y)的联合分布律为 X\Y0100.10.210.30.4 (1)求E(X) 先求x的边缘分布律,表格里x0的概率为0.10.2,于是我们可得 X01P0.30.7直接求E(X)即可,得到结果 (2)求E(XY) 直接x与y相乘就行。 记得别乘多了,别的算了又…...

MySQL 搞定行转列,列转行
行转列方法总结1、使用case…when…then2、使用SUM(IF()) 生成列3、使用SUM(IF()) 生成列 WITH ROLLUP 生成汇总行4、使用SUM(IF()) 生成列 UNION 生成汇总行,并利用 IFNULL将汇总行标题显示为 Total5、使用SUM(IF()) 生成列,直接生成汇总结果,不再利用…...

正点原子裸机开发之C语言点灯程序
一. 简介 本文针对 IMX6ULL 的裸机开发的(即不带Linux操作系统的开发)。 主要分两部分的工作: 1. 配置 C语言运行环境 2. C 语言编写及运行 二. 配置C语言运行环境 配置 C 语言运行环境的工作分 三部分。如下: 1. 设置…...

cv::阈值分割OTUS原理+代码
opencv库的阈值分割分为全局分割和局部分割全局分割:普通分割ret1,th1 cv2.threshold(img,127, 255, cv2.THRESH_BINARY) #127为阈值 #cv2.THRESH_BINARY |cv2.THRESH_BINARY_INV | cv2.THRESH_TRUNC|cv2.THRESH_TOZERO|cv2.THRESH_TOZERO_INV局部分割:…...

Postgresql-12.5 visual studio-2022 windows 添加pg工程并调试
pg内核学习,记录一下 文章目录安装包编译安装VS添加Postgresql工程调试源码安装包 (1)perl下载 https://www.perl.org/get.html (2)diff下载 http://gnuwin32.sourceforge.net/packages/diffutils.htm (…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...

aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...