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

springBoot中自定义一个validation注解,实现指定枚举值校验

缘由

在后台写接口的时候,经常会出现dto某个属性是映射到一个枚举的情况。有时候还会出现只能映射到枚举类中部分枚举值的情况。以前都是在service里面自行判断,很多地方代码冗余,所以就想着弄一个自定义的validation注解来实现。
例如下面某个DTO的属性transmissionType,需要映射到TransmissionType枚举类

/*** @see TransmissionType#getCode()*/
private Integer transmissionType;

代码

新建一个接口

新建这个接口是为了后面获取枚举的code值,大部分时候,枚举的code都是int类型的,所以这里也只考虑了这种情况。如果是其他类型的,需要自行改造一下。比如另外建一个类型的接口,在EnumCodeValidator类里面判断处理。不想再建接口的话,就在此接口里面加一个返回code类型的方法。然后根据类型来决定是调用getCode获取值还是getCodeStr获取。

/*** 公共的接口,用于在validator里面获取枚举的code值,这里只考虑int类型的。*/
public interface EnumCode {int getCode();
}

新建一个注解

这个注解除了指定枚举类之外,还可以指定要包含或排除的枚举名称(是名称,在ConstraintValidator是通过枚举name方法拿名称的)

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 验证枚举值注解<br>* 枚举的code需要是int类型*/
@Constraint(validatedBy = EnumCodeValidator.class)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidEnumCode {/*** 对应的枚举类的Class*/Class<? extends Enum<?>> enumClass();/*** 过滤的枚举名称 表示需要哪些名称的*/String[] filterEnumName() default {};/*** 排除的名称名称*/String[] excludeEnumName() default {};String message() default "值必须是已存在的枚举值";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}

自定义验证器,实现ConstraintValidator接口

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;/*** 具体的校验规则*/
public class EnumCodeValidator implements ConstraintValidator<ValidEnumCode, Integer> {private Class<? extends Enum<?>> enumClass;private String[] filter;private String[] exclude;@Overridepublic void initialize(ValidEnumCode constraintAnnotation) {this.enumClass = constraintAnnotation.enumClass();this.filter = constraintAnnotation.filterEnumName();this.exclude = constraintAnnotation.excludeEnumName();}@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {if (value == null) {return true;}Enum<?>[] enums = enumClass.getEnumConstants();boolean filterEmpty = ArrayUtil.isEmpty(filter);boolean excludeNonEmpty = ArrayUtil.isNotEmpty(exclude);List<Integer> validCodes = Arrays.stream(enums).filter(e -> {if (excludeNonEmpty) {for (String excludeName : exclude) {if (StrUtil.equals(excludeName, e.name())) {return false;}}}if (filterEmpty) {return true;}for (String filterName : filter) {if (StrUtil.equals(filterName, e.name())) {return true;}}return false;}).mapToInt(e -> ((EnumCode) e).getCode()).boxed().collect(Collectors.toList());return validCodes.contains(value);}
}

使用

枚举类先implements EnumCode接口
在这里插入图片描述

常见的三种情况

  1. 必须是TransmissionType枚举类中的属性值
     /*** @see TransmissionType#getCode()*/@ValidEnumCode(enumClass = TransmissionType.class)private Integer transmissionType;
    
  2. 必须是TransmissionType枚举类中的属性值,且名称为STRATEGYNEWS
     public R<List<LinkVO>> newArticle(@RequestParam("articleType")@ValidEnumCode(enumClass = ArticleType.class,filterEnumName = {"STRATEGY", "NEWS"}) Integer articleType) {
    
  3. 必须是TransmissionType枚举类中的属性值,且排除掉名称为STRATEGYNEWS
     public R<ArticlesVO> getInfoByArticleType(@RequestParam("articleType")@ValidEnumCode(enumClass = ArticleType.class,excludeEnumName = {"STRATEGY", "NEWS"}) Integer articleType) {
    

相关文章:

  • 【JEECG】BasicTable单元格编辑,插槽添加下拉组件样式错位
  • 【Trea】Trea国际版|海外版下载
  • Suno v4.5:AI 音乐创作的新突破
  • SLAM:正定矩阵二次型的定义和性质
  • GD32/STM32 ADC/DMA使用指南
  • 人工智能端侧热度再起
  • hybird接口配置
  • FTPS和SFTP(文件传输安全协议)
  • ProteinTools辅助探索蛋白稳定性、动态调控以及结构关系
  • windows操作系统开机自启(自动启动) 运行窗口 shell:startup 指令调出开机自启文件夹
  • mux-vlan基础配置
  • Linux服务之nginx中http设置及虚拟主机搭建
  • day 13 不平衡数据集的处理
  • ctfshow web入门 web52
  • 【coze】记忆体(变量、数据库、长期记忆、消息盒子)
  • B站视频下载到电脑的方法总结
  • 商业实战将归巢网内容构建为本地RAG模型的完整指南01-优雅草卓伊凡
  • 开发搭载OneNet平台的物联网数据收发APP的设计与实现
  • 【大模型面试】大模型(LLMs)高频面题全面整理(★2025年5月最新版★)
  • Python+Scrapy跨境电商爬虫实战:从亚马逊/沃尔玛数据采集到反爬攻克(附Pangolin API高效方案)
  • 央行:全力推进一揽子金融政策加快落地
  • 印方称若巴方决定升级局势,印方已做好反击准备
  • 吴清:全力支持中央汇金公司发挥好类“平准基金”作用
  • 潘功胜:将下调个人住房公积金贷款利率0.25个百分点
  • 金融政策支持稳市场稳预期发布会即将召开,潘功胜、李云泽、吴清将出席
  • 大规模空袭也门一日后,以军又对也门萨那机场发出撤离警告