Swagger Enum 枚举支持注释

目录

1、首先创建注解

2、创建接口 Desc

3、创建类SwaggerPlugin

4、使用方式

4.1 添加注解

4.2 枚举类实现Desc接口,重写getCode和getDesc方法

4.3 效果图


正常swagger 提供的参数说明无法识别到枚举的字段值, 只能显示name,通过实现 ModelPropertyBuilderPlugin 自定义description可以实现自己想要的效果

1、首先创建注解

import io.swagger.annotations.ApiModelProperty;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 对 {@link ApiModelProperty}进行增强,支持枚举类展示和字典展示。
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiModelPropertyPro {

    /**
     * 同 {@link ApiModelProperty#value()}相同
     */
    String value() default "";

    /**
     * 要翻译的字典
     */
    String dictType() default "";

    /**
     * 要翻译的枚举类,枚举类接口需要实现 {@link Desc} 接口
     */
    Class<? extends Desc>[] enumClass() default {};

}

2、创建接口 Desc

枚举类实现此接口,用于展示描述信息

public interface Desc {

    String getCode();

    String getDesc();
}

3、创建类SwaggerPlugin

这个类主要用于定制模型属性。

DictUtils是我们项目中获取字典的工具类,如果你不需要翻译字典可以删除,如果需要请自行修改。

 
import com.ccse.cimp.common.security.utils.DictUtils;
import com.ccse.cimp.system.api.domain.SysDictData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;
import springfox.documentation.builders.PropertySpecificationBuilder;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin;
import springfox.documentation.spi.schema.contexts.ModelPropertyContext;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

@Configuration
@Slf4j
public class SwaggerPlugin implements ModelPropertyBuilderPlugin {

    private static final String delimiter = "、";

    /**
     * 应用方法,用于为模型属性应用Swagger注解
     *
     * @param context 模型属性上下文
     */
    @Override
    public void apply(ModelPropertyContext context) {
        context.getBeanPropertyDefinition()
                .ifPresent(beanPropertyDefinition -> addDesc(context, beanPropertyDefinition.getField().getAnnotated()));

    }

    /**
     * 为枚举类型或字典类型的属性添加描述
     *
     * @param context 模型属性上下文
     * @param field   属性字段
     */
    private void addDesc(ModelPropertyContext context, Field field) {
        // 获取ApiModelPropertyPro注解
        ApiModelPropertyPro anno = field.getAnnotation(ApiModelPropertyPro.class);
        if (anno == null) {
            return;
        }

        List<String> displayValues = new ArrayList<>();

        // 获取枚举值的显示字符串列表
        Class<? extends Desc>[] classes = anno.enumClass();
        if (!ObjectUtils.isEmpty(classes)) {
            displayValues.addAll(getDisplayValues(classes));
        }

        // 获取字典类型的显示字符串列表
        String dictType = anno.dictType();
        if (StringUtils.isNotEmpty(dictType)) {
            displayValues.addAll(getDisplayValues(dictType));
        }

        // 获取属性的规范构建器
        PropertySpecificationBuilder builder = context.getSpecificationBuilder();

        // 构建描述字符串
        String value = anno.value();
        String joinText = value.isEmpty() ? "" : (value + ":(") + String.join(delimiter, displayValues) + ")";

        // 设置描述
        builder.description(joinText);

    }

    /**
     * 根据枚举类型获取其显示值列表
     *
     * @param classes 枚举类
     * @return 枚举值的显示字符串列表
     */
    private List<String> getDisplayValues(Class<? extends Desc>[] classes) {

        List<String> displayValues=new ArrayList<>();

        for (Class<? extends Desc> enumClass : classes) {

            //获取此枚举类的元素,如果此 Class 对象不是枚举类型,则返回 null
            Desc[] enumConstants = enumClass.getEnumConstants();
            if (ObjectUtils.isEmpty(enumConstants)) {
               continue;
            }
            displayValues.addAll(Arrays.stream(enumConstants)
                    .map(item -> item.getCode() + ":" + item.getDesc())
                    .collect(Collectors.toList()));
        }

        return displayValues;

    }

    /**
     * 根据字典类型获取其显示值列表
     *
     * @param dictType 字典类型
     * @return 字典值的显示字符串列表
     */
    private List<String> getDisplayValues(String dictType) {
        List<SysDictData> dictCache = DictUtils.getDictCache(dictType);
        if (CollectionUtils.isEmpty(dictCache)) {
            return Collections.emptyList();
        }

        return dictCache.stream()
                .map(item -> item.getDictValue() + ":" + item.getDictLabel())
                .collect(Collectors.toList());
    }

    /**
     * 判断插件是否支持文档类型
     *
     * @param documentationType 文档类型
     * @return 如果支持,则返回true;否则返回false
     */
    @Override
    public boolean supports(@NotNull DocumentationType documentationType) {
        return true;
    }
}

4、使用方式

4.1 添加注解

4.2 枚举类实现Desc接口,重写getCode和getDesc方法

4.3 效果图

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值