目录
4.2 枚举类实现Desc接口,重写getCode和getDesc方法
正常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;
}
}