swagger2.7隐藏入参中属性字段解决办法

第一步:

创建swagger2要忽略的注解

package com.example.annotation;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
// swagger忽略的参数
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreSwaggerParameter {
}

第二步:重写ModelAttributeParameterExpander修改了方法getBeanPropertyNames

import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.members.ResolvedField;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.*;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.schema.Collections;
import springfox.documentation.schema.Maps;
import springfox.documentation.schema.Types;
import springfox.documentation.schema.property.field.FieldProvider;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.schema.AlternateTypeProvider;
import springfox.documentation.spi.service.contexts.DocumentationContext;
import springfox.documentation.spi.service.contexts.ParameterExpansionContext;
import springfox.documentation.spring.web.plugins.DocumentationPluginsManager;
import springfox.documentation.spring.web.readers.parameter.ExpansionContext;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeField;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;
import sun.reflect.misc.FieldUtil;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * @author liuqixiang
 * @date 2020-01-01 下午2:00
 */
@Component
@Primary
public class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander {
    private static final Logger LOG = LoggerFactory.getLogger(CustomizeModelAttributeParameterExpander.class);
    private final FieldProvider fieldProvider;
    @Autowired
    protected DocumentationPluginsManager pluginsManager;

    @Autowired
    public CustomizeModelAttributeParameterExpander(FieldProvider fields) {
        super(fields);
        this.fieldProvider = fields;
    }

    public List<Parameter> expand(ExpansionContext context) {
        List<Parameter> parameters = Lists.newArrayList();
        Set<String> beanPropNames = this.getBeanPropertyNames(context.getParamType().getErasedType());
        Iterable<ResolvedField> fields = FluentIterable.from(this.fieldProvider.in(context.getParamType())).filter(this.onlyBeanProperties(beanPropNames));
        LOG.debug("Expanding parameter type: {}", context.getParamType());
        AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();
        FluentIterable<ModelAttributeField> modelAttributes = FluentIterable.from(fields).transform(this.toModelAttributeField(alternateTypeProvider));
        FluentIterable<ModelAttributeField> expendables = modelAttributes.filter(Predicates.not(this.simpleType())).filter(Predicates.not(this.recursiveType(context)));
        Iterator i$ = expendables.iterator();

        while(i$.hasNext()) {
            ModelAttributeField each = (ModelAttributeField)i$.next();
            LOG.debug("Attempting to expand expandable field: {}", each.getField());
            parameters.addAll(this.expand(context.childContext(this.nestedParentName(context.getParentName(), each.getField()), each.getFieldType(), context.getDocumentationContext())));
        }

        FluentIterable<ModelAttributeField> collectionTypes = modelAttributes.filter(Predicates.and(this.isCollection(), Predicates.not(this.recursiveCollectionItemType(context.getParamType()))));
        i$ = collectionTypes.iterator();

        while(true) {
            while(i$.hasNext()) {
                ModelAttributeField each = (ModelAttributeField)i$.next();
                LOG.debug("Attempting to expand collection/array field: {}", each.getField());
                ResolvedType itemType = Collections.collectionElementType(each.getFieldType());
                if (!Types.isBaseType(itemType) && !itemType.getErasedType().isEnum()) {
                    parameters.addAll(this.expand(context.childContext(this.nestedParentName(context.getParentName(), each.getField()), itemType, context.getDocumentationContext())));
                } else {
                    parameters.add(this.simpleFields(context.getParentName(), context.getDocumentationContext(), each));
                }
            }

            FluentIterable<ModelAttributeField> simpleFields = modelAttributes.filter(this.simpleType());
            i$ = simpleFields.iterator();

            while(i$.hasNext()) {
                ModelAttributeField each = (ModelAttributeField)i$.next();
                parameters.add(this.simpleFields(context.getParentName(), context.getDocumentationContext(), each));
            }

            return FluentIterable.from(parameters).filter(Predicates.not(this.hiddenParameters())).toList();
        }
    }

    private Predicate<ModelAttributeField> recursiveCollectionItemType(final ResolvedType paramType) {
        return new Predicate<ModelAttributeField>() {
            public boolean apply(ModelAttributeField input) {
                return Objects.equal(Collections.collectionElementType(input.getFieldType()), paramType);
            }
        };
    }

    private Predicate<Parameter> hiddenParameters() {
        return new Predicate<Parameter>() {
            public boolean apply(Parameter input) {
                return input.isHidden();
            }
        };
    }

    private Parameter simpleFields(String parentName, DocumentationContext documentationContext, ModelAttributeField each) {
        LOG.debug("Attempting to expand field: {}", each);
        String dataTypeName = (String)Optional.fromNullable(Types.typeNameFor(each.getFieldType().getErasedType())).or(each.getFieldType().getErasedType().getSimpleName());
        LOG.debug("Building parameter for field: {}, with type: ", each, each.getFieldType());
        ParameterExpansionContext parameterExpansionContext = new ParameterExpansionContext(dataTypeName, parentName, each.getField(), documentationContext.getDocumentationType(), new ParameterBuilder());
        return this.pluginsManager.expandParameter(parameterExpansionContext);
    }

    private Predicate<ModelAttributeField> recursiveType(final ExpansionContext context) {
        return new Predicate<ModelAttributeField>() {
            public boolean apply(ModelAttributeField input) {
                return context.hasSeenType(input.getFieldType());
            }
        };
    }

    private Predicate<ModelAttributeField> simpleType() {
        return Predicates.and(new Predicate[]{Predicates.not(this.isCollection()), Predicates.not(this.isMap()), Predicates.or(new Predicate[]{this.belongsToJavaPackage(), this.isBaseType(), this.isEnum()})});
    }

    private Predicate<ModelAttributeField> isCollection() {
        return new Predicate<ModelAttributeField>() {
            public boolean apply(ModelAttributeField input) {
                return Collections.isContainerType(input.getFieldType());
            }
        };
    }

    private Predicate<ModelAttributeField> isMap() {
        return new Predicate<ModelAttributeField>() {
            public boolean apply(ModelAttributeField input) {
                return Maps.isMapType(input.getFieldType());
            }
        };
    }

    private Predicate<ModelAttributeField> isEnum() {
        return new Predicate<ModelAttributeField>() {
            public boolean apply(ModelAttributeField input) {
                return input.getFieldType().getErasedType().isEnum();
            }
        };
    }

    private Predicate<ModelAttributeField> belongsToJavaPackage() {
        return new Predicate<ModelAttributeField>() {
            public boolean apply(ModelAttributeField input) {
                return CustomizeModelAttributeParameterExpander.this.packageName(input.getFieldType().getErasedType()).startsWith("java.lang");
            }
        };
    }

    private Predicate<ModelAttributeField> isBaseType() {
        return new Predicate<ModelAttributeField>() {
            public boolean apply(ModelAttributeField input) {
                return Types.isBaseType(input.getFieldType()) || input.getField().getType().isPrimitive();
            }
        };
    }

    private Function<ResolvedField, ModelAttributeField> toModelAttributeField(final AlternateTypeProvider alternateTypeProvider) {
        return new Function<ResolvedField, ModelAttributeField>() {
            public ModelAttributeField apply(ResolvedField input) {
                return new ModelAttributeField(CustomizeModelAttributeParameterExpander.this.fieldType(alternateTypeProvider, input), input);
            }
        };
    }

    private Predicate<ResolvedField> onlyBeanProperties(final Set<String> beanPropNames) {
        return new Predicate<ResolvedField>() {
            public boolean apply(ResolvedField input) {
                return beanPropNames.contains(input.getName());
            }
        };
    }

    private String nestedParentName(String parentName, ResolvedField field) {
        String name = field.getName();
        ResolvedType fieldType = field.getType();
        if (Collections.isContainerType(fieldType) && !Types.isBaseType(Collections.collectionElementType(fieldType))) {
            name = name + "[0]";
        }

        return Strings.isNullOrEmpty(parentName) ? name : String.format("%s.%s", parentName, name);
    }

    private ResolvedType fieldType(AlternateTypeProvider alternateTypeProvider, ResolvedField field) {
        return alternateTypeProvider.alternateFor(field.getType());
    }

    private String packageName(Class<?> type) {
        return (String) Optional.fromNullable(type.getPackage()).transform(this.toPackageName()).or("java");
    }

    private Function<Package, String> toPackageName() {
        return new Function<Package, String>() {
            public String apply(Package input) {
                return input.getName();
            }
        };
    }

    private Set<String> getBeanPropertyNames(Class<?> clazz) {
        try {
            Set<String> beanProps = new HashSet();
            PropertyDescriptor[] propDescriptors = this.getBeanInfo(clazz).getPropertyDescriptors();
            PropertyDescriptor[] arr$ = propDescriptors;
            int len$ = propDescriptors.length;
            for(int i$ = 0; i$ < len$; ++i$) {
                PropertyDescriptor propDescriptor = arr$[i$];
                //增加忽略逻辑 忽略IgnoreSwaggerParameter注解字段
                Field field = FieldUtils.getDeclaredField(clazz, propDescriptor.getName(), true);
                if (field!=null) {
                    field.setAccessible(true);
                    IgnoreSwaggerParameter ignoreSwaggerParameter = field.getDeclaredAnnotation(IgnoreSwaggerParameter.class);
                    if (ignoreSwaggerParameter != null) {
                        continue;
                    }
                }
                // 增加结束

                if (propDescriptor.getReadMethod() != null) {
                    beanProps.add(propDescriptor.getName());
                }
            }

            return beanProps;
        } catch (IntrospectionException var8) {
            LOG.warn(String.format("Failed to get bean properties on (%s)", clazz), var8);
            return Sets.newHashSet();
        }
    }

    @VisibleForTesting
    BeanInfo getBeanInfo(Class<?> clazz) throws IntrospectionException {
        return Introspector.getBeanInfo(clazz);
    }
}

 

在实体类属性上添加 @IgnoreSwaggerParameter即可

 @ApiModelProperty(value = "部门信息")
    @IgnoreSwaggerParameter // 在不需要递归展开的属性上加上IgnoreSwaggerParameter注解
    private Dept dept;

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值