ruoyi 若依 自定义注解 参数校验
可以使用“枚举统一接口 自定义注解 ConstraintValidator”实现。你的项目是 Spring Boot 3校验包应使用jakarta.validation。1. 定义枚举统一接口package com.ruoyi.common.enums; /** * 具有业务编码的枚举。 * * param T 编码类型 */ public interface CodeEnumT { T getCode(); }2. 让业务枚举实现接口例如内容类型枚举package com.ruoyi.GMLG.enums; import com.ruoyi.common.enums.CodeEnum; public enum ContentTypeEnum implements CodeEnumString { VIDEO(video, 视频), AUDIO(audio, 音频), ARTICLE(article, 图文); private final String code; private final String label; ContentTypeEnum(String code, String label) { this.code code; this.label label; } Override public String getCode() { return code; } public String getLabel() { return label; } }Long类型也可以直接实现public enum ContentStatusEnum implements CodeEnumLong { PENDING_SUBMIT(0L, 待提交), APPROVING(1L, 审批中), APPROVED(2L, 已通过), REJECTED(3L, 已驳回); private final Long code; private final String label; ContentStatusEnum(Long code, String label) { this.code code; this.label label; } Override public Long getCode() { return code; } public String getLabel() { return label; } }你现有枚举已经有getCode()只需要添加implements CodeEnumString或implements CodeEnumLong。3. 创建自定义校验注解package com.ruoyi.common.annotation; import com.ruoyi.common.validation.EnumValueValidator; import jakarta.validation.Constraint; import jakarta.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; Documented Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) Retention(RetentionPolicy.RUNTIME) Constraint(validatedBy EnumValueValidator.class) public interface EnumValue { /** * 需要校验的枚举类。 */ Class? extends Enum? enumClass(); String message() default 参数值不在允许的枚举范围内; Class?[] groups() default {}; Class? extends Payload[] payload() default {}; }4. 实现枚举校验器package com.ruoyi.common.validation; import com.ruoyi.common.annotation.EnumValue; import com.ruoyi.common.enums.CodeEnum; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; public class EnumValueValidator implements ConstraintValidatorEnumValue, Object { private SetObject allowedValues; Override public void initialize(EnumValue annotation) { Enum?[] enumConstants annotation.enumClass().getEnumConstants(); if (enumConstants null) { throw new IllegalArgumentException( annotation.enumClass().getName() 不是枚举类 ); } allowedValues Arrays.stream(enumConstants) .map(item - { if (!(item instanceof CodeEnum? codeEnum)) { throw new IllegalArgumentException( annotation.enumClass().getName() 必须实现 CodeEnum 接口 ); } return codeEnum.getCode(); }) .collect(Collectors.toUnmodifiableSet()); } Override public boolean isValid( Object value, ConstraintValidatorContext context) { // null 是否允许由 NotNull 单独负责 if (value null) { return true; } return allowedValues.contains(value); } }这里直接比较实际类型video匹配String0反序列化到Long字段后匹配Long不会把字符串0错当成长整型0L5. 在实体字段上使用import com.ruoyi.GMLG.enums.ClassifyStatusEnum; import com.ruoyi.GMLG.enums.ContentStatusEnum; import com.ruoyi.GMLG.enums.ContentTypeEnum; import com.ruoyi.GMLG.enums.PromoteStatusEnum; import com.ruoyi.GMLG.enums.PublishScopeEnum; import com.ruoyi.common.annotation.EnumValue; import jakarta.validation.constraints.NotNull; public class GmLgContent { NotNull(message 内容类型不能为空) EnumValue( enumClass ContentTypeEnum.class, message 内容类型只能是 video、audio 或 article ) private String contentType; EnumValue( enumClass PublishScopeEnum.class, message 发布范围只能是 all、city 或 third ) private String publishScope; EnumValue( enumClass ContentStatusEnum.class, message 内容状态只能是 0、1、2 或 3 ) private Long status; EnumValue( enumClass PromoteStatusEnum.class, message 推广状态只能是 0、1 或 2 ) private Long promoteStatus; EnumValue( enumClass ClassifyStatusEnum.class, message 归类状态只能是 0 或 1 ) private Long classifyStatus; }6. Controller 必须触发参数校验你当前的 GMLG Controller 没有使用Validated因此只给字段添加注解还不会生效。新增接口应改成import org.springframework.validation.annotation.Validated; PostMapping public AjaxResult add( Validated RequestBody GmLgContent gmLgContent) { return toAjax( gmLgContentService.insertGmLgContent(gmLgContent) ); }修改接口同样添加PutMapping public AjaxResult edit( Validated RequestBody GmLgContent gmLgContent) { return toAjax( gmLgContentService.updateGmLgContent(gmLgContent) ); }若提交{ contentType: document, status: 9 }若依现有的GlobalExceptionHandler会处理MethodArgumentNotValidException返回类似{ code: 500, msg: 内容类型只能是 video、audio 或 article }注意EnumValue默认允许null需要必填的字段再叠加NotNull或NotBlank。这样新增、修改等不同场景也更容易通过校验分组控制。

相关新闻

GLinker 百万级实体链接:GLiNER 背后的知识图谱野心

GLinker 百万级实体链接:GLiNER 背后的知识图谱野心

GLinker 百万级实体链接:GLiNER 背后的知识图谱野心 【免费下载链接】gliner2.5-multi-v1 项目地址: https://ai.gitcode.com/hf_mirrors/fastino/gliner2.5-multi-v1 命名实体识别(NER)做到极致之后,下一步是什么&#x…

2026/10/11 21:57:43 阅读更多 →
基于梯度缺陷ANCF梁单元的单悬臂梁大变形MATLAB仿真

基于梯度缺陷ANCF梁单元的单悬臂梁大变形MATLAB仿真

做柔性体大变形仿真的同行应该都有过这种经历:用传统梁单元算一个细长悬臂梁在重力下的大幅弯曲,结果要么计算不收敛,要么转角一大就“锁死”,甚至直接报负特征值。这个基于梯度缺陷ANCF梁单元的单悬臂梁重力弯曲MATLAB仿真&#…

2026/10/11 21:57:43 阅读更多 →
SOLIDWORKS成功背后:HOOPS如何赋能工程软件3D开发

SOLIDWORKS成功背后:HOOPS如何赋能工程软件3D开发

这几年跟不少做工程软件、CAD/CAM/CAE的研发团队聊下来,有个话题总是绕不开:为什么大家一说做3D功能,第一反应就是看HOOPS这类组件?甚至很多从SOLIDWORKS身上找灵感的产品经理,最后也绕回到HOOPS上。细想一下不奇怪。S…

2026/10/11 21:56:43 阅读更多 →

最新新闻

新浪Level2接口SDK接入实战:授权、协议解析与避坑指南

新浪Level2接口SDK接入实战:授权、协议解析与避坑指南

简介:新浪Level2接口SDK是一份面向量化开发与行情分析人员的Java工程,用于对接新浪Level2全推行情,获取股票、基金等品种的深度交易数据。相比普通免费接口,Level2数据在速度与深度上更适合机构级策略,适合有一定Java基…

2026/10/11 22:50:35 阅读更多 →
一个 Key 调用所有模型:2026 四大聚合平台价格、生态与稳定性横评

一个 Key 调用所有模型:2026 四大聚合平台价格、生态与稳定性横评

大模型 API 聚合平台的核心价值一句话就能说清:一个 Key 接入多家大模型,统一计费与访问管理,把供应商切换成本降到最低。市面上的主流玩家分三类——国际商业聚合、国内商业聚合、自托管开源方案,路线不同,取舍也不同…

2026/10/11 22:50:35 阅读更多 →
HOP上游升级SOP:pnpm upstream:update一键同步rhwp并全链路验证的完整流程

HOP上游升级SOP:pnpm upstream:update一键同步rhwp并全链路验证的完整流程

【免费下载链接】hop 项目地址: https://gitcode.com/gh_mirrors/hop22/hop 点击查看 免费下载 HOP 是一款开源的 HWP/HWPX 文档编辑器,桌面外壳由 HOP 团队维护,而文档解析与渲染引擎来自上游项目 rhwp。如何安全地跟随上游版本前进&#x…

2026/10/11 22:50:35 阅读更多 →
Android游戏逆向重构实战:从植物大战僵尸源码2到可运行工程

Android游戏逆向重构实战:从植物大战僵尸源码2到可运行工程

简介:本资源为《植物大战僵尸》Android平台开源实现的完整工程源码,面向Android游戏开发初学者与进阶者,聚焦塔防类游戏架构设计、图形渲染与状态管理等核心实践。压缩包共173个文件,含20个Java源文件(涵盖GameScene、…

2026/10/11 22:50:35 阅读更多 →
基于线性回归的PM2.5预测系统Python源码实战解析

基于线性回归的PM2.5预测系统Python源码实战解析

简介:基于线性回归的PM2.5预测系统源码,是一套面向Python学习者、机器学习入门者及大气环境数据分析场景的小型完整项目。代码以单文件Python脚本承载数据读取、特征构造、模型训练与结果预测等关键流程,配套原始训练/测试CSV表、处理后的特征…

2026/10/11 22:50:35 阅读更多 →
PgQue 监控实战:5 个必须告警的队列健康指标 + 如何揪出卡住的消费者

PgQue 监控实战:5 个必须告警的队列健康指标 + 如何揪出卡住的消费者

【免费下载链接】PgQue PgQue – Zero-bloat Postgres queue built on top of on battle-proven Skypes PgQ. One SQL file to install, pg_cron to tick https://pgque.dev 项目地址: https://gitcode.com/gh_mirrors/pg/PgQue 点击查看 免费下载 PgQue 是一个零膨…

2026/10/11 22:49:35 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →