springboot整合Swagger的方式就不说了,百度上面有很多资源,主要就是Swagger在忽略属性时不生效的解决方法:
内容转载来自: https://blog.csdn.net/weixin_44980618/article/details/102883844
原内容中已经解决了忽略属性的问题,我增加了忽略父级属性的小操作,希望不断丰富。我用的是2.9.
问题:
假如接收参数的实体类中关联了其他对象,那么swagger2的页面中参数应该会多出来这些,dept.id,dept.deptName,或者集合属性,roles[0].id,roles[0].roleName等等。
这些属性有可能是不需要用来接收参数的,出现在文档中会给前端开发人员带来困惑
笔者在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()