美文网首页
swagger2自定义隐藏实体类属性

swagger2自定义隐藏实体类属性

作者: 吟风者 | 来源:发表于2019-07-23 15:08 被阅读0次

    假如接收参数的实体类中关联了其他对象,那么swagger2的页面中参数应该会多出来这些,dept.id,dept.deptName,或者集合属性,roles[0].id,roles[0].roleName等等。
    ​​​这些属性有可能是不需要用来接收参数的,出现在文档中会给前端开发人员带来困惑

    image

    笔者在swagger2提供的配置中没有找到隐藏此类参数的设置

    但是通过阅读源码找到了展开参数的类springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander,笔者通过继承这个类,并添加@Primary注解覆盖了源码中的逻辑,修改了getBeanPropertyNames方法,其他不变

    swagger2版本2.8.0 解决方案

    
    package com.example.swagger;
     
    import com.example.annotation.IgnoreSwaggerParameter;
    import com.fasterxml.classmate.ResolvedType;
    import com.fasterxml.classmate.members.ResolvedField;
    import com.google.common.annotations.VisibleForTesting;
    import com.google.common.base.Function;
    import com.google.common.base.Optional;
    import com.google.common.base.Predicate;
    import com.google.common.collect.FluentIterable;
    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 org.springframework.util.ClassUtils;
    import springfox.documentation.builders.ParameterBuilder;
    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.schema.EnumTypeDeterminer;
    import springfox.documentation.spi.service.contexts.DocumentationContext;
    import springfox.documentation.spi.service.contexts.ParameterExpansionContext;
    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 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.List;
    import java.util.Set;
     
    import static com.google.common.base.Objects.equal;
    import static com.google.common.base.Predicates.*;
    import static com.google.common.base.Strings.isNullOrEmpty;
    import static com.google.common.collect.FluentIterable.from;
    import static com.google.common.collect.Lists.newArrayList;
    import static com.google.common.collect.Sets.newHashSet;
    import static springfox.documentation.schema.Collections.collectionElementType;
    import static springfox.documentation.schema.Collections.isContainerType;
    import static springfox.documentation.schema.Types.typeNameFor;
     
    /**
     * 覆盖{@link ModelAttributeParameterExpander}
     * @see CustomizeModelAttributeParameterExpander#getBeanPropertyNames(Class)
     * @see ModelAttributeParameterExpander#getBeanPropertyNames(Class)
     * @see IgnoreSwaggerParameter
     */
    @Component
    @Primary
    public class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander {
     
        private static final Logger LOG = LoggerFactory.getLogger(CustomizeModelAttributeParameterExpander.class);
        private final FieldProvider fieldProvider;
        private final EnumTypeDeterminer enumTypeDeterminer;
     
        @Autowired
        public CustomizeModelAttributeParameterExpander(FieldProvider fields, EnumTypeDeterminer enumTypeDeterminer) {
            super(fields, enumTypeDeterminer);
            this.fieldProvider = fields;
            this.enumTypeDeterminer = enumTypeDeterminer;
        }
     
        @Override
        public List<Parameter> expand(ExpansionContext context) {
     
            List<Parameter> parameters = newArrayList();
            Set<String> beanPropNames = getBeanPropertyNames(context.getParamType().getErasedType());
            Iterable<ResolvedField> fields = FluentIterable.from(fieldProvider.in(context.getParamType()))
                    .filter(onlyBeanProperties(beanPropNames));
            LOG.debug("Expanding parameter type: {}", context.getParamType());
            AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();
     
            FluentIterable<ModelAttributeField> modelAttributes = from(fields)
                    .transform(toModelAttributeField(alternateTypeProvider));
     
            FluentIterable<ModelAttributeField> expendables = modelAttributes
                    .filter(not(simpleType()))
                    .filter(not(recursiveType(context)));
            for (ModelAttributeField each : expendables) {
                LOG.debug("Attempting to expand expandable field: {}", each.getField());
                parameters.addAll(
                        expand(
                                context.childContext(
                                        nestedParentName(context.getParentName(), each.getField()),
                                        each.getFieldType(),
                                        context.getDocumentationContext())));
            }
     
            FluentIterable<ModelAttributeField> collectionTypes = modelAttributes
                    .filter(and(isCollection(), not(recursiveCollectionItemType(context.getParamType()))));
            for (ModelAttributeField each : collectionTypes) {
                LOG.debug("Attempting to expand collection/array field: {}", each.getField());
     
                ResolvedType itemType = collectionElementType(each.getFieldType());
                if (Types.isBaseType(itemType) || enumTypeDeterminer.isEnum(itemType.getErasedType())) {
                    parameters.add(simpleFields(context.getParentName(), context.getDocumentationContext(), each));
                } else {
                    parameters.addAll(
                            expand(
                                    context.childContext(
                                            nestedParentName(context.getParentName(), each.getField()),
                                            itemType,
                                            context.getDocumentationContext())));
                }
            }
     
            FluentIterable<ModelAttributeField> simpleFields = modelAttributes.filter(simpleType());
            for (ModelAttributeField each : simpleFields) {
                parameters.add(simpleFields(context.getParentName(), context.getDocumentationContext(), each));
            }
            return FluentIterable.from(parameters).filter(not(hiddenParameters())).toList();
        }
     
        private Predicate<ModelAttributeField> recursiveCollectionItemType(final ResolvedType paramType) {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return equal(collectionElementType(input.getFieldType()), paramType);
                }
            };
        }
     
        private Predicate<Parameter> hiddenParameters() {
            return new Predicate<Parameter>() {
                @Override
                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 = Optional.fromNullable(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 pluginsManager.expandParameter(parameterExpansionContext);
        }
     
     
        private Predicate<ModelAttributeField> recursiveType(final ExpansionContext context) {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return context.hasSeenType(input.getFieldType());
                }
            };
        }
     
        private Predicate<ModelAttributeField> simpleType() {
            return and(not(isCollection()), not(isMap()),
                    or(
                            belongsToJavaPackage(),
                            isBaseType(),
                            isEnum()));
        }
     
        private Predicate<ModelAttributeField> isCollection() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return isContainerType(input.getFieldType());
                }
            };
        }
     
        private Predicate<ModelAttributeField> isMap() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return Maps.isMapType(input.getFieldType());
                }
            };
        }
     
        private Predicate<ModelAttributeField> isEnum() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType());
                }
            };
        }
     
        private Predicate<ModelAttributeField> belongsToJavaPackage() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith("java.lang");
                }
            };
        }
     
        private Predicate<ModelAttributeField> isBaseType() {
            return new Predicate<ModelAttributeField>() {
                @Override
                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>() {
                @Override
                public ModelAttributeField apply(ResolvedField input) {
                    return new ModelAttributeField(fieldType(alternateTypeProvider, input), input);
                }
            };
        }
     
        private Predicate<ResolvedField> onlyBeanProperties(final Set<String> beanPropNames) {
            return new Predicate<ResolvedField>() {
                @Override
                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 (isContainerType(fieldType) && !Types.isBaseType(collectionElementType(fieldType))) {
                name += "[0]";
            }
     
            if (isNullOrEmpty(parentName)) {
                return name;
            }
            return String.format("%s.%s", parentName, name);
        }
     
        private ResolvedType fieldType(AlternateTypeProvider alternateTypeProvider, ResolvedField field) {
            return alternateTypeProvider.alternateFor(field.getType());
        }
     
        private Set<String> getBeanPropertyNames(final Class<?> clazz) {
     
            try {
                Set<String> beanProps = new HashSet<String>();
                PropertyDescriptor[] propDescriptors = getBeanInfo(clazz).getPropertyDescriptors();
     
                for (PropertyDescriptor propDescriptor : propDescriptors) {
     
                    // 增加逻辑,忽略@IgnoreSwaggerParameter注解的字段
                    //Field field = clazz.getDeclaredField(propDescriptor.getName());
                    // 根据 Zy馒头  的反馈,上面的方式获取父类的字段会出错,所以使用了hutool工具包,大家可以根据自己的需要自行下载
           // <dependency>
           //     <groupId>cn.hutool</groupId>
           //     <artifactId>hutool-all</artifactId>
           //     <version>5.2.0</version>
           //</dependency>
    
                    Field  field = ReflectUtil.getField(clazz, descriptor.getName());
                    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 (Exception e) {
                LOG.warn(String.format("Failed to get bean properties on (%s)", clazz), e);
            }
            return newHashSet();
        }
     
        @VisibleForTesting
        BeanInfo getBeanInfo(Class<?> clazz) throws IntrospectionException {
            return Introspector.getBeanInfo(clazz);
        }
     
    }
    
    

    swagger2版本2.9.2 解决方案

    package com.zihuiinfo.facesdk.framework.common.swagger;
    
    import com.fasterxml.classmate.ResolvedType;
    import com.fasterxml.classmate.members.ResolvedField;
    import com.fasterxml.classmate.members.ResolvedMethod;
    import com.google.common.annotations.VisibleForTesting;
    import com.google.common.base.Function;
    import com.google.common.base.Optional;
    import com.google.common.base.Predicate;
    import com.google.common.collect.FluentIterable;
    import com.google.common.collect.Sets;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Primary;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.MediaType;
    import org.springframework.stereotype.Component;
    import org.springframework.util.ClassUtils;
    import springfox.documentation.builders.ParameterBuilder;
    import springfox.documentation.schema.Maps;
    import springfox.documentation.schema.Types;
    import springfox.documentation.schema.property.bean.AccessorsProvider;
    import springfox.documentation.schema.property.field.FieldProvider;
    import springfox.documentation.service.Parameter;
    import springfox.documentation.spi.schema.AlternateTypeProvider;
    import springfox.documentation.spi.schema.EnumTypeDeterminer;
    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 springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterMetadataAccessor;
    
    import java.beans.BeanInfo;
    import java.beans.IntrospectionException;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.*;
    
    import static com.google.common.base.Objects.equal;
    import static com.google.common.base.Predicates.*;
    import static com.google.common.base.Strings.isNullOrEmpty;
    import static com.google.common.collect.FluentIterable.from;
    import static com.google.common.collect.Lists.newArrayList;
    import static com.google.common.collect.Sets.newHashSet;
    import static springfox.documentation.schema.Collections.collectionElementType;
    import static springfox.documentation.schema.Collections.isContainerType;
    import static springfox.documentation.schema.Types.isVoid;
    import static springfox.documentation.schema.Types.typeNameFor;
    
    /**
     * 覆盖{@link ModelAttributeParameterExpander}
     *
     * @see CustomizeModelAttributeParameterExpander#getBeanPropertyNames(Class)
     * @see ModelAttributeParameterExpander#getBeanPropertyNames(Class)
     * @see IgnoreSwaggerParameter
     */
    @Component
    @Primary
    public class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander {
        private static final Logger LOG = LoggerFactory.getLogger(ModelAttributeParameterExpander.class);
        private final FieldProvider fields;
        private final AccessorsProvider accessors;
        private final EnumTypeDeterminer enumTypeDeterminer;
    
        @Autowired
        protected DocumentationPluginsManager pluginsManager;
    
        @Autowired
        public CustomizeModelAttributeParameterExpander(FieldProvider fields, AccessorsProvider accessors, EnumTypeDeterminer enumTypeDeterminer) {
            super(fields, accessors, enumTypeDeterminer);
            this.fields = fields;
            this.accessors = accessors;
            this.enumTypeDeterminer = enumTypeDeterminer;
        }
    
        public List<Parameter> expand(ExpansionContext context) {
            List<Parameter> parameters = newArrayList();
            Set<PropertyDescriptor> propertyDescriptors = propertyDescriptors(context.getParamType().getErasedType());
            Map<Method, PropertyDescriptor> propertyLookupByGetter
                    = propertyDescriptorsByMethod(context.getParamType().getErasedType(), propertyDescriptors);
            Iterable<ResolvedMethod> getters = FluentIterable.from(accessors.in(context.getParamType()))
                    .filter(onlyValidGetters(propertyLookupByGetter.keySet()));
    
            Map<String, ResolvedField> fieldsByName = FluentIterable.from(this.fields.in(context.getParamType()))
                    .uniqueIndex(new Function<ResolvedField, String>() {
                        @Override
                        public String apply(ResolvedField input) {
                            return input.getName();
                        }
                    });
    
    
            LOG.debug("Expanding parameter type: {}", context.getParamType());
            final AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();
    
            FluentIterable<ModelAttributeField> attributes =
                    allModelAttributes(
                            propertyLookupByGetter,
                            getters,
                            fieldsByName,
                            alternateTypeProvider);
    
            FluentIterable<ModelAttributeField> expendables = attributes
                    .filter(not(simpleType()))
                    .filter(not(recursiveType(context)));
            for (ModelAttributeField each : expendables) {
                LOG.debug("Attempting to expand expandable property: {}", each.getName());
                parameters.addAll(
                        expand(
                                context.childContext(
                                        nestedParentName(context.getParentName(), each),
                                        each.getFieldType(),
                                        context.getOperationContext())));
            }
    
            FluentIterable<ModelAttributeField> collectionTypes = attributes
                    .filter(and(isCollection(), not(recursiveCollectionItemType(context.getParamType()))));
            for (ModelAttributeField each : collectionTypes) {
                LOG.debug("Attempting to expand collection/array field: {}", each.getName());
    
                ResolvedType itemType = collectionElementType(each.getFieldType());
                if (Types.isBaseType(itemType) || enumTypeDeterminer.isEnum(itemType.getErasedType())) {
                    parameters.add(simpleFields(context.getParentName(), context, each));
                } else {
                    ExpansionContext childContext = context.childContext(
                            nestedParentName(context.getParentName(), each),
                            itemType,
                            context.getOperationContext());
                    if (!context.hasSeenType(itemType)) {
                        parameters.addAll(expand(childContext));
                    }
                }
            }
    
            FluentIterable<ModelAttributeField> simpleFields = attributes.filter(simpleType());
            for (ModelAttributeField each : simpleFields) {
                parameters.add(simpleFields(context.getParentName(), context, each));
            }
            return FluentIterable.from(parameters)
                    .filter(not(hiddenParameters()))
                    .filter(not(voidParameters()))
                    .toList();
        }
    
        private FluentIterable<ModelAttributeField> allModelAttributes(
                Map<Method, PropertyDescriptor> propertyLookupByGetter,
                Iterable<ResolvedMethod> getters,
                Map<String, ResolvedField> fieldsByName,
                AlternateTypeProvider alternateTypeProvider) {
    
            FluentIterable<ModelAttributeField> modelAttributesFromGetters = from(getters)
                    .transform(toModelAttributeField(fieldsByName, propertyLookupByGetter, alternateTypeProvider));
    
            FluentIterable<ModelAttributeField> modelAttributesFromFields = from(fieldsByName.values())
                    .filter(publicFields())
                    .transform(toModelAttributeField(alternateTypeProvider));
    
            return FluentIterable.from(Sets.union(
                    modelAttributesFromFields.toSet(),
                    modelAttributesFromGetters.toSet()));
        }
    
        private Function<ResolvedField, ModelAttributeField> toModelAttributeField(
                final AlternateTypeProvider alternateTypeProvider) {
    
            return new Function<ResolvedField, ModelAttributeField>() {
                @Override
                public ModelAttributeField apply(ResolvedField input) {
                    return new ModelAttributeField(
                            alternateTypeProvider.alternateFor(input.getType()),
                            input.getName(),
                            input,
                            input);
                }
            };
        }
    
        private Predicate<ResolvedField> publicFields() {
            return new Predicate<ResolvedField>() {
                @Override
                public boolean apply(ResolvedField input) {
                    return input.isPublic();
                }
            };
        }
    
        private Predicate<Parameter> voidParameters() {
            return new Predicate<Parameter>() {
                @Override
                public boolean apply(Parameter input) {
                    return isVoid(input.getType().orNull());
                }
            };
        }
    
        private Predicate<ModelAttributeField> recursiveCollectionItemType(final ResolvedType paramType) {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return equal(collectionElementType(input.getFieldType()), paramType);
                }
            };
        }
    
        private Predicate<Parameter> hiddenParameters() {
            return new Predicate<Parameter>() {
                @Override
                public boolean apply(Parameter input) {
                    return input.isHidden();
                }
            };
        }
    
        private Parameter simpleFields(
                String parentName,
                ExpansionContext context,
                ModelAttributeField each) {
            LOG.debug("Attempting to expand field: {}", each);
            String dataTypeName = Optional.fromNullable(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,
                    determineScalarParameterType(
                            context.getOperationContext().consumes(),
                            context.getOperationContext().httpMethod()),
                    new ModelAttributeParameterMetadataAccessor(
                            each.annotatedElements(),
                            each.getFieldType(),
                            each.getName()),
                    context.getDocumentationContext().getDocumentationType(),
                    new ParameterBuilder());
            return pluginsManager.expandParameter(parameterExpansionContext);
        }
    
        private Predicate<ModelAttributeField> recursiveType(final ExpansionContext context) {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return context.hasSeenType(input.getFieldType());
                }
            };
        }
    
        private Predicate<ModelAttributeField> simpleType() {
            return and(not(isCollection()), not(isMap()),
                    or(
                            belongsToJavaPackage(),
                            isBaseType(),
                            isEnum()));
        }
    
        private Predicate<ModelAttributeField> isCollection() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return isContainerType(input.getFieldType());
                }
            };
        }
    
        private Predicate<ModelAttributeField> isMap() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return Maps.isMapType(input.getFieldType());
                }
            };
        }
    
        private Predicate<ModelAttributeField> isEnum() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType());
                }
            };
        }
    
        private Predicate<ModelAttributeField> belongsToJavaPackage() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith("java.lang");
                }
            };
        }
    
        private Predicate<ModelAttributeField> isBaseType() {
            return new Predicate<ModelAttributeField>() {
                @Override
                public boolean apply(ModelAttributeField input) {
                    return Types.isBaseType(input.getFieldType())
                            || input.getFieldType().isPrimitive();
                }
            };
        }
    
        private Function<ResolvedMethod, ModelAttributeField> toModelAttributeField(
                final Map<String, ResolvedField> fieldsByName,
                final Map<Method, PropertyDescriptor> propertyLookupByGetter,
                final AlternateTypeProvider alternateTypeProvider) {
            return new Function<ResolvedMethod, ModelAttributeField>() {
                @Override
                public ModelAttributeField apply(ResolvedMethod input) {
                    String name = propertyLookupByGetter.get(input.getRawMember()).getName();
                    return new ModelAttributeField(
                            fieldType(alternateTypeProvider, input),
                            name,
                            input,
                            fieldsByName.get(name));
                }
            };
        }
    
        private Predicate<ResolvedMethod> onlyValidGetters(final Set<Method> methods) {
            return new Predicate<ResolvedMethod>() {
                @Override
                public boolean apply(ResolvedMethod input) {
                    return methods.contains(input.getRawMember());
                }
            };
        }
    
        private String nestedParentName(String parentName, ModelAttributeField attribute) {
            String name = attribute.getName();
            ResolvedType fieldType = attribute.getFieldType();
            if (isContainerType(fieldType) && !Types.isBaseType(collectionElementType(fieldType))) {
                name += "[0]";
            }
    
            if (isNullOrEmpty(parentName)) {
                return name;
            }
            return String.format("%s.%s", parentName, name);
        }
    
        private ResolvedType fieldType(AlternateTypeProvider alternateTypeProvider, ResolvedMethod method) {
            return alternateTypeProvider.alternateFor(method.getType());
        }
    
        private Set<PropertyDescriptor> propertyDescriptors(final Class<?> clazz) {
            try {
                Set<PropertyDescriptor> beanProps = new HashSet<>();
                PropertyDescriptor[] descriptors = getBeanInfo(clazz).getPropertyDescriptors();
    
                for (PropertyDescriptor descriptor : descriptors) {
                    Field field = null;
                    try {
                       // field = clazz.getDeclaredField(descriptor.getName());
                    // 根据 Zy馒头  的反馈,上面的方式获取父类的字段会出错,所以使用了hutool工具包,大家可以根据自己的需要自行下载
           // <dependency>
           //     <groupId>cn.hutool</groupId>
           //     <artifactId>hutool-all</artifactId>
           //     <version>5.2.0</version>
           //</dependency>
     field = ReflectUtil.getField(clazz, descriptor.getName());
                    } catch (Exception e) {
                        LOG.debug(String.format("Failed to get bean properties on (%s)", clazz), e);
                    }
                    if (field != null) {
                        field.setAccessible(true);
                        IgnoreSwaggerParameter ignoreSwaggerParameter = field.getDeclaredAnnotation(IgnoreSwaggerParameter.class);
                        if (ignoreSwaggerParameter != null) {
                            continue;
                        }
                    }
    
                    if (descriptor.getReadMethod() != null) {
                        beanProps.add(descriptor);
                    }
                }
                return beanProps;
            } catch (Exception e) {
                LOG.warn(String.format("Failed to get bean properties on (%s)", clazz), e);
            }
            return newHashSet();
        }
    
        private Map<Method, PropertyDescriptor> propertyDescriptorsByMethod(
                final Class<?> clazz,
                Set<PropertyDescriptor> propertyDescriptors) {
            return FluentIterable.from(propertyDescriptors)
                    .filter(new Predicate<PropertyDescriptor>() {
                        @Override
                        public boolean apply(PropertyDescriptor input) {
                            return input.getReadMethod() != null
                                    && !clazz.isAssignableFrom(Collection.class)
                                    && !"isEmpty".equals(input.getReadMethod().getName());
                        }
                    })
                    .uniqueIndex(new Function<PropertyDescriptor, Method>() {
                        @Override
                        public Method apply(PropertyDescriptor input) {
                            return input.getReadMethod();
                        }
                    });
    
        }
    
        @VisibleForTesting
        BeanInfo getBeanInfo(Class<?> clazz) throws IntrospectionException {
            return Introspector.getBeanInfo(clazz);
        }
    
        public static String determineScalarParameterType(Set<? extends MediaType> consumes, HttpMethod method) {
            String parameterType = "query";
    
            if (consumes.contains(MediaType.APPLICATION_FORM_URLENCODED)
                    && method == HttpMethod.POST) {
                parameterType = "form";
            } else if (consumes.contains(MediaType.MULTIPART_FORM_DATA)
                    && method == HttpMethod.POST) {
                parameterType = "formData";
            }
    
            return parameterType;
        }
    }
    
    

    用到了自定义的IgnoreSwaggerParamer注解

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

    使用方式,在不需要递归展开的属性上加上IgnoreSwaggerParameter注解

    
    package com.example.model.po;
     
    import com.example.annotation.IgnoreSwaggerParameter;
    import com.example.model.BaseModel;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
     
    import java.sql.Date;
    import java.sql.Timestamp;
    import java.util.List;
     
    @Data
    @ApiModel(value = "用户")
    public class User extends BaseModel {
     
        private static final long serialVersionUID = 1L;
        @ApiModelProperty(value = "用户id")
        private Integer id;
        @ApiModelProperty(value = "用户名")
        private String username;
        @ApiModelProperty(value = "密码")
        private String password;
        @ApiModelProperty(value = "邮箱")
        private String email;
        @ApiModelProperty(value = "昵称")
        private String nickname;
        @ApiModelProperty(value = "生日")
        private Date birth;
        @ApiModelProperty(value="登录时间")
        private Timestamp logintime;
        @ApiModelProperty(value = "部门id")
        private Integer deptId;
     
        @ApiModelProperty(value = "部门信息")
        @IgnoreSwaggerParameter // 在不需要递归展开的属性上加上IgnoreSwaggerParameter注解
        private Dept dept;
    }
    

    这样就可以自定义隐藏swagger2页面中的参数了。

    如果有用的不对的地方,欢迎各位大佬批评指正。

    如有疑问请参考源码:swagger2,文档和示例略有不同,有什么疑问请留言。


    作者:薛凌康
    来源:CSDN
    原文:https://blog.csdn.net/qq_35433926/article/details/89514913
    版权声明:本文为博主原创文章,转载请附上博文链接!

    相关文章

      网友评论

          本文标题:swagger2自定义隐藏实体类属性

          本文链接:https://www.haomeiwen.com/subject/ghwolctx.html