Swagger @ApiModelProperty 绑定枚举类

先看效果

1.自定义注解

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

/**
 * @description:  swagger 属性绑定 枚举对象注解
 * @author guyi
 * @date 2023/11/24 9:53
 **/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiModelPropertyEnum {
    Class value();
}

2.实现Swagger 的 ModelPropertyBuilderPlugin 接口


import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.TypeResolver;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import springfox.documentation.schema.Annotations;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin;
import springfox.documentation.spi.schema.contexts.ModelPropertyContext;
import springfox.documentation.spring.web.DescriptionResolver;
import springfox.documentation.swagger.common.SwaggerPluginSupport;
import springfox.documentation.swagger.schema.ApiModelProperties;

import java.lang.reflect.*;
import java.util.Map;
import java.util.Optional;

/**
 * @Description: 自定义 Swagger 属性绑定
 * @Author: guyi
 * @Date: 2023-11-24 09:58
 **/
@Component
@Order(-2147482648)
public class MyModelPropertyBuilderPlugin implements ModelPropertyBuilderPlugin {

    private final DescriptionResolver descriptions;

    @Autowired
    public MyModelPropertyBuilderPlugin(DescriptionResolver descriptions) {
        this.descriptions = descriptions;
    }

    @Override
    public void apply(ModelPropertyContext context) {
        Optional<ApiModelProperty> annotation = Optional.empty();
        if (context.getAnnotatedElement().isPresent()) {
            annotation = (Optional) annotation.map(Optional::of).orElse(ApiModelProperties.findApiModePropertyAnnotation((AnnotatedElement) context.getAnnotatedElement().get()));
        }

        if (context.getBeanPropertyDefinition().isPresent()) {
            annotation = (Optional) annotation.map(Optional::of).orElse(Annotations.findPropertyAnnotation((BeanPropertyDefinition) context.getBeanPropertyDefinition().get(), ApiModelProperty.class));
        }

        if (annotation.isPresent()) {
            ApiModelProperty apiModelProperty = annotation.get();
            ApiModelPropertyEnum apiModelPropertyEnum = context.getBeanPropertyDefinition().get().getField().getAnnotation(ApiModelPropertyEnum.class);
            try {
                StringBuilder stringBuilder = null;
                if (apiModelPropertyEnum != null && !apiModelProperty.value().contains("(")) {
                    InvocationHandler invocationHandler = Proxy.getInvocationHandler(apiModelProperty);
                    Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
                    memberValues.setAccessible(true);
                    Map o = (Map) memberValues.get(invocationHandler);
                    Class<?> aClass = apiModelPropertyEnum.value();
                    Object[] enumConstants = aClass.getEnumConstants();
                    stringBuilder = new StringBuilder();
                    stringBuilder.append(apiModelProperty.value());
                    stringBuilder.append("(");
                    for (Object enumConstant : enumConstants) {
                        Method[] declaredMethods = aClass.getDeclaredMethods();
                        for (Method declaredMethod : declaredMethods) {
                            String name = declaredMethod.getName();
                            if (name.equals("values") || name.equals("valueOf")) {
                                continue;
                            }
                            stringBuilder.append(declaredMethod.invoke(enumConstant));
                            stringBuilder.append(":");
                        }
                        stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
                        stringBuilder.append(",");
                    }
                    stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
                    stringBuilder.append(")");
                    o.put("value", stringBuilder.toString());
                }
                context.getBuilder()
                        .allowableValues(apiModelProperty.allowableValues() == null ? null : ApiModelProperties.allowableValueFromString(apiModelProperty.allowableValues()))
                        .required(apiModelProperty.required())
                        .readOnly(apiModelProperty.readOnly())
                        .description(stringBuilder == null ? null : stringBuilder.toString())
                        .isHidden(apiModelProperty.hidden())
                        .type(resolve(context.getResolver(), apiModelProperty))
                        .position(apiModelProperty.position());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public ResolvedType resolve(TypeResolver resolver, ApiModelProperty apiModelProperty) {
        try {
            return resolver.resolve(Class.forName(apiModelProperty.dataType()), new Type[0]);
        } catch (ClassNotFoundException e) {
            return resolver.resolve(Object.class, new Type[0]);
        }

    }

    @Override
    public boolean supports(DocumentationType delimiter) {
        return SwaggerPluginSupport.pluginDoesApply(delimiter);
    }
}

3.定义枚举对象

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * @Description: 通用枚举类,把所有枚举类都写到一起
 * @Author: guyi
 * @Date: 2023-11-24 14:00
 **/
public final class ComEnum {



    /**
     *  通用字典表-是否(0-否,1-是)
     */
    @Getter
    @AllArgsConstructor
    public enum YESORNO {
        NO("0","否"),
        YES("1","是");

        private final String value;
        private final String label;
    }



    /**
     *  荣誉获奖表--获奖级别(1-国家级、2-省级、3-市级、4-区级、5-校级)
     */
    @Getter
    @AllArgsConstructor
    public enum AwardsHistoryLevel {
        NATION("1","国家级"),
//        PROVINCE("2","省级"),
        CITY("3","市级"),
        AREA("4","区级"),
        SCHOOL("5","校级");

        private final String value;
        private final String label;
    }
    

}

4.注解使用

	/**获奖级别*/
    @ApiModelProperty(value = "获奖级别")
    @ApiModelPropertyEnum(value = ComEnum.AwardsHistoryLevel.class)
    private String level;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值