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

swagger通过配置将enum自动添加到字段说明中

项目场景:


解决方案:

我们需要一个注解去标注enum的位置


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiModelEnumProperty {/*** enum的类路径 需要实现IBaseEnum接口* @return*/String value();}

枚举需要实现接口


public interface EnumInterface<T> {// 由枚举类去实现, 通过lombok可以直接无感实现T getCode();// 由枚举类去实现, 通过lombok可以直接无感实现String getDesc();default String description() {return getCode() + "-" + getDesc();}
}

然后需要配置swagger配置类


import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.ExpandedParameterBuilderPlugin;
import springfox.documentation.spi.service.ParameterBuilderPlugin;
import springfox.documentation.spi.service.contexts.ParameterContext;
import springfox.documentation.spi.service.contexts.ParameterExpansionContext;import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;/*** swagger配置类 实现modelProperty插件接口*/
@Slf4j
@Configuration
public class SwaggerParamsBuilderPlugin implements ParameterBuilderPlugin, ExpandedParameterBuilderPlugin {@Overridepublic void apply(ParameterExpansionContext context) {descForEnumProperty(context);}@Overridepublic void apply(ParameterContext context) {// 为枚举字段加注释descForEnumProperty(context);}private void descForEnumProperty(ParameterContext context) {ResolvedMethodParameter resolvedMethodParameter = context.resolvedMethodParameter();// 找ApiModelProperty类Optional<ApiModelProperty> propertyAnnotation = resolvedMethodParameter.findAnnotation(ApiModelProperty.class);if (!propertyAnnotation.isPresent()) {// 不存在ApiModelProperty 直接返回return;}// 尝试找到ApiModelEnumProperty注解Optional<ApiModelEnumProperty> enumPropertyAnnotation = resolvedMethodParameter.findAnnotation(ApiModelEnumProperty.class);if (!enumPropertyAnnotation.isPresent()) {// 不存在ApiModelEnumProperty 直接返回return;}// 尝试找到ApiModelEnumProperty修饰的enum类型Class enumRawTypeClass;try {enumRawTypeClass = Class.forName(enumPropertyAnnotation.get().value());if (!Enum.class.isAssignableFrom(enumRawTypeClass) || !EnumInterface.class.isAssignableFrom(enumRawTypeClass)) {throw new BusinessException(ResponseEnum.CODE_ERROR.getReturnCode(), "ApiModelEnumProperty修饰的类型需要实现EnumInterface接口,且需要为enum");}Object[] enumConstants = enumRawTypeClass.getEnumConstants();List<String> enumDisplayDescList = StreamUtils.toStream(enumConstants).map(item -> ((EnumInterface<?>) item).description()).filter(Objects::nonNull).collect(Collectors.toList());context.requestParameterBuilder().description(propertyAnnotation.get().value() + "枚举值: " + StringUtils.join(enumDisplayDescList, "; "));} catch (ClassNotFoundException e) {log.error("swagger enum解析异常, 类型不存在" ,e);}}private void descForEnumProperty(ParameterExpansionContext context) {// 找ApiModelProperty类Optional<ApiModelProperty> propertyAnnotation = context.findAnnotation(ApiModelProperty.class);if (!propertyAnnotation.isPresent()) {// 不存在ApiModelProperty 直接返回return;}// 尝试找到ApiModelEnumProperty注解Optional<ApiModelEnumProperty> enumPropertyAnnotation = context.findAnnotation(ApiModelEnumProperty.class);if (!enumPropertyAnnotation.isPresent()) {// 不存在ApiModelEnumProperty 直接返回return;}// 尝试找到ApiModelEnumProperty修饰的enum类型Class enumRawTypeClass;try {enumRawTypeClass = Class.forName(enumPropertyAnnotation.get().value());if (!Enum.class.isAssignableFrom(enumRawTypeClass) || !EnumInterface.class.isAssignableFrom(enumRawTypeClass)) {throw new BusinessException(ResponseEnum.CODE_ERROR.getReturnCode(), "ApiModelEnumProperty修饰的类型需要实现EnumInterface接口,且需要为enum");}Object[] enumConstants = enumRawTypeClass.getEnumConstants();List<String> enumDisplayDescList = StreamUtils.toStream(enumConstants).map(item -> ((EnumInterface<?>) item).description()).filter(Objects::nonNull).collect(Collectors.toList());context.getRequestParameterBuilder().description(propertyAnnotation.get().value() + "枚举值: " + StringUtils.join(enumDisplayDescList, "; "));} catch (ClassNotFoundException e) {log.error("swagger enum解析异常, 类型不存在" ,e);}}@Overridepublic boolean supports(DocumentationType documentationType) {return true;}}

import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.schema.Annotations;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin;
import springfox.documentation.spi.schema.contexts.ModelPropertyContext;import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;/*** swagger配置类 实现modelProperty插件接口*/
@Slf4j
@Configuration
public class SwaggerModelPropertyBuilderPlugin implements ModelPropertyBuilderPlugin {@Overridepublic void apply(ModelPropertyContext context) {// 为枚举字段加注释descForEnumProperty(context);}private void descForEnumProperty(ModelPropertyContext context) {if (!context.getBeanPropertyDefinition().isPresent()) {return;}// 找ApiModelProperty类Optional<ApiModelProperty> propertyAnnotation = Annotations.findPropertyAnnotation(context.getBeanPropertyDefinition().get(), ApiModelProperty.class);if (!propertyAnnotation.isPresent()) {// 不存在ApiModelProperty 直接返回return;}// 尝试找到ApiModelEnumProperty注解Optional<ApiModelEnumProperty> enumPropertyAnnotation = Annotations.findPropertyAnnotation(context.getBeanPropertyDefinition().get(), ApiModelEnumProperty.class);if (!enumPropertyAnnotation.isPresent()) {// 不存在ApiModelEnumProperty 直接返回return;}// 尝试找到ApiModelEnumProperty修饰的enum类型Class enumRawTypeClass;try {enumRawTypeClass = Class.forName(enumPropertyAnnotation.get().value());if (!Enum.class.isAssignableFrom(enumRawTypeClass) || !EnumInterface.class.isAssignableFrom(enumRawTypeClass)) {throw new BusinessException(ResponseEnum.CODE_ERROR.getReturnCode(), "ApiModelEnumProperty修饰的类型需要实现EnumInterface接口,且需要为enum");}Object[] enumConstants = enumRawTypeClass.getEnumConstants();List<String> enumDisplayDescList = StreamUtils.toStream(enumConstants).map(item -> ((EnumInterface<?>) item).description()).filter(Objects::nonNull).collect(Collectors.toList());context.getSpecificationBuilder().description(propertyAnnotation.get().value() + "枚举值: " + StringUtils.join(enumDisplayDescList, "; "));} catch (ClassNotFoundException e) {log.error("swagger enum解析异常, 类型不存在" ,e);}}@Overridepublic boolean supports(DocumentationType documentationType) {return true;}
}
http://www.xdnf.cn/news/986023.html

相关文章:

  • PHP如何检查一个字符串是否是email格式
  • 【微信小程序】| 在线咖啡点餐平台设计与实现
  • 华为云Flexus+DeepSeek征文 | 基于华为云ModelArts Studio打造AingDesk AI聊天助手
  • list类型
  • SCADA|测试KingSCADA4.0信创版采集汇川PLC AC810数据
  • 开源夜莺支持MySQL数据源,更方便做业务指标监控了
  • xss分析
  • C2f模块 vs Darknet-53——YOLOv8检测效率的提升
  • 9.IP数据包分片计算
  • HNCTF2025 - Misc、Osint、Crypto WriteUp
  • 第三讲 基础运算之整数运算
  • 什么是数字化项目风险管理?如何实现项目风险管理数字化?
  • IIS 实现 HTTPS:OpenSSL证书生成与配置完整指南
  • 突然虚拟机磁盘只剩下几十K
  • [特殊字符] React 与 Vue 源码级对比:5大核心差异与实战选择指南
  • # include<heαd.h>和# include″heαd.h″的区别
  • 成都国际数字影像产业园孵化培育模式的探索与突破
  • 人机交互设计知识点总结
  • 驻波比(VSWR)详解
  • 判断字符串子序列
  • OpenAI o3-pro深度解析:87%降价背后的AI战略,AGI发展迈入新阶段!
  • 自动托盘搬运车是什么?它的工作逻辑如何实现物流自动化?
  • Python训练营打卡 Day51
  • 日本滨松R669光电倍增管Hamamatsu直径51 mm 直径端窗型扩展红多碱光阴极面光谱灵敏度特性:300 至 900 nm
  • AI重写工具导致‘文本湍流’特征|如何人工消除算法识别标记
  • 卷积神经网络(一)
  • 基于C++实现(控制台)小学算数自测系统
  • ateⅹⅰt()的用法
  • DD3118完整版参数规格书|DD3118 3.0读卡器控制方案|DD3118高速3.0读卡器芯片
  • 【数据采集+人形机器人】使用 Apple Vision Pro 对宇树(Unitree)G1 和 H1 人形机器人进行全身的遥操作控制