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;}
}