当前位置: 首页 > news >正文

自定义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. 组合总和

每天一题&#xff0c;防止痴呆题目示例分析思路1题解1分析思路2题解2&#x1f449;️ 力扣原文 题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形…...

【Linux】vi和vim编辑器

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

BIO,NIO,AIO

IO模型 用什么样的通道进行数据传输和接收&#xff0c;java支持3种io网络编程模式 BIO NIO AIO BIO 同步阻塞 一个客户端连接对应一个处理线程 BIO示例代码&#xff08;客户端和服务端&#xff09; package com.tuling.bio;import java.io.IOException; import java.net.So…...

代码随想录刷题-数组-有序数组的平方

文章目录有序数组的平方习题暴力排序双指针有序数组的平方 本节对应代码随想录中&#xff1a;代码随想录&#xff0c;讲解视频&#xff1a;有序数组的平方_哔哩哔哩_bilibili 习题 题目链接&#xff1a;977. 有序数组的平方 - 力扣&#xff08;LeetCode&#xff09; 给你一…...

【玩转c++】stack和queue的介绍和模拟实现

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

Linux order(文件、磁盘、网络、系统管理、备份压缩)

1. Linux 文件命令 -rwxrwxrwx chmod&#xff1a;change mode&#xff0c;用于&#xff08;文件所有者或 root &#xff09;变更用户(u:owner g:group o:other a:all)的权限 chmod [OPTION]… MODE[,MODE]… FILE… OPTION -R&#xff1a;递归修改more option&#xff1a;chmod…...

最详细的CentOS7安装Mysql数据库服务

1.查看是否安装mysql: rpm -qa | grep mysql如果有查出来东西&#xff0c;使用命令删除&#xff1a; rpm -e xxx2.检查是否有mysql用户组和mysql用户,没有就添加有就忽略&#xff1a; groups mysql 添加用户组和用户 groupadd mysql && useradd -r -g mysql mysql&a…...

【IoT】项目管理:如何做好端到端的项目管理?

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

渲染十万条数据就把你难住了?不存在的!

虚拟列表的使用场景如果我想要在网页中放大量的列表项&#xff0c;纯渲染的话&#xff0c;对于浏览器性能将会是个极大的挑战&#xff0c;会造成滚动卡顿&#xff0c;整体体验非常不好&#xff0c;主要有以下问题&#xff1a;页面等待时间极长&#xff0c;用户体验差CPU计算能力…...

编程学习的心路历程和困惑回顾

回首入行9年的经历&#xff0c;从大一开始学习C语言和数据结构&#xff0c;老师一直是在用IDE演示程序的编写和运行&#xff0c;我们也就一直在跟黑乎乎的命令行窗口打交道。 后来在一些课程的实验环节&#xff0c;接触到了一些别人编写好的工程代码&#xff0c;知道了Makefile…...

请介绍类加载过程,什么是双亲委派模型?

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

Navisworks编辑材质和Revit快速切换材质问题

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

Object对象键值的输出循序到底如何排列的?

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

气泡式水位计的安装方法详解

气泡水位计的安装实际上就是气管的安装&#xff0c;气管的安装是否正确将直接影响到仪器测量数据的结果&#xff0c;气泡水位计它由活塞泵产生的压缩空气流经测量管和气泡室&#xff0c;进入被测的水体中&#xff0c;测量管中的静压力与气泡室上的水位高度成正比。那么接下来就…...

求“二维随机变量的期望E(X)与方差D(X)”例题(一)

离散型 设随机变量(X,Y)的联合分布律为 X\Y0100.10.210.30.4 (1)求E(X) 先求x的边缘分布律&#xff0c;表格里x0的概率为0.10.2&#xff0c;于是我们可得 X01P0.30.7直接求E(X)即可&#xff0c;得到结果 (2)求E(XY) 直接x与y相乘就行。 记得别乘多了&#xff0c;别的算了又…...

MySQL 搞定行转列,列转行

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

正点原子裸机开发之C语言点灯程序

一. 简介 本文针对 IMX6ULL 的裸机开发的&#xff08;即不带Linux操作系统的开发&#xff09;。 主要分两部分的工作&#xff1a; 1. 配置 C语言运行环境 2. C 语言编写及运行 二. 配置C语言运行环境 配置 C 语言运行环境的工作分 三部分。如下&#xff1a; 1. 设置…...

cv::阈值分割OTUS原理+代码

opencv库的阈值分割分为全局分割和局部分割全局分割&#xff1a;普通分割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局部分割&#xff1a;…...

Postgresql-12.5 visual studio-2022 windows 添加pg工程并调试

pg内核学习&#xff0c;记录一下 文章目录安装包编译安装VS添加Postgresql工程调试源码安装包 &#xff08;1&#xff09;perl下载 https://www.perl.org/get.html &#xff08;2&#xff09;diff下载 http://gnuwin32.sourceforge.net/packages/diffutils.htm &#xff08;…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

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

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

拟合问题处理

在机器学习中&#xff0c;核心任务通常围绕模型训练和性能提升展开&#xff0c;但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正&#xff1a; 一、机器学习的核心任务框架 机…...