第一步:
创建swagger2要忽略的注解
第二步:
重写ModelAttributeParameterExpander修改了方法propertyDescriptors
/**
* @author ycx
* @title: CustomizeModelAttributeParameterExpander
* @description: TODO
* @date 2020/3/2911:52
*/
@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;
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 = Lists.newArrayList();
Set<PropertyDescriptor> propertyDescriptors = this.propertyDescriptors(context.getParamType().getErasedType());
Map<Method, PropertyDescriptor> propertyLookupByGetter = this.propertyDescriptorsByMethod(context.getParamType().getErasedType(), propertyDescriptors);
Iterable<ResolvedMethod> getters = FluentIterable.from(this.accessors.in(context.getParamType())).filter(this.onlyValidGetters(propertyLookupByGetter.keySet()));
Map<String, ResolvedField> fieldsByName = FluentIterable.from(this.fields.in(context.getParamType())).uniqueIndex(new Function<ResolvedField, String>() {
public String apply(ResolvedField input) {
return input.getName();
}
});
LOG.debug("Expanding parameter type: {}", context.getParamType());
AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();
FluentIterable<ModelAttributeField> attributes = this.allModelAttributes(propertyLookupByGetter, getters, fieldsByName, alternateTypeProvider);
FluentIterable<ModelAttributeField> expendables = attributes.filter(Predicates.not(this.simpleType())).filter(Predicates.not(this.recursiveType(context)));
Iterator var10 = expendables.iterator();
while (var10.hasNext()) {
ModelAttributeField each = (ModelAttributeField) var10.next();
LOG.debug("Attempting to expand expandable property: {}", each.getName());
parameters.addAll(this.expand(context.childContext(this.nestedParentName(context.getParentName(), each), each.getFieldType(), context.getOperationContext())));
}
FluentIterable<ModelAttributeField> collectionTypes = attributes.filter(Predicates.and(this.isCollection(), Predicates.not(this.recursiveCollectionItemType(context.getParamType()))));
Iterator var16 = collectionTypes.iterator();
while (true) {
while (var16.hasNext()) {
ModelAttributeField each = (ModelAttributeField) var16.next();
LOG.debug("Attempting to expand collection/array field: {}", each.getName());
ResolvedType itemType = Collections.collectionElementType(each.getFieldType());
if (!Types.isBaseType(itemType) && !this.enumTypeDeterminer.isEnum(itemType.getErasedType())) {
ExpansionContext childContext = context.childContext(this.nestedParentName(context.getParentName(), each), itemType, context.getOperationContext());
if (!context.hasSeenType(itemType)) {
parameters.addAll(this.expand(childContext));
}
} else {
parameters.add(this.simpleFields(context.getParentName(), context, each));
}
}
FluentIterable<ModelAttributeField> simpleFields = attributes.filter(this.simpleType());
Iterator var18 = simpleFields.iterator();
while (var18.hasNext()) {
ModelAttributeField each = (ModelAttributeField) var18.next();
parameters.add(this.simpleFields(context.getParentName(), context, each));
}
return FluentIterable.from(parameters).filter(Predicates.not(this.hiddenParameters())).filter(Predicates.not(this.voidParameters())).toList();
}
}
private FluentIterable<ModelAttributeField> allModelAttributes(Map<Method, PropertyDescriptor> propertyLookupByGetter, Iterable<ResolvedMethod> getters, Map<String, ResolvedField> fieldsByName, AlternateTypeProvider alternateTypeProvider) {
FluentIterable<ModelAttributeField> modelAttributesFromGetters = FluentIterable.from(getters).transform(this.toModelAttributeField(fieldsByName, propertyLookupByGetter, alternateTypeProvider));
FluentIterable<ModelAttributeField> modelAttributesFromFields = FluentIterable.from(fieldsByName.values()).filter(this.publicFields()).transform(this.toModelAttributeField(alternateTypeProvider));
return FluentIterable.from(Sets.union(modelAttributesFromFields.toSet(), modelAttributesFromGetters.toSet()));
}
private Function<ResolvedField, ModelAttributeField> toModelAttributeField(final AlternateTypeProvider alternateTypeProvider) {
return new Function<ResolvedField, ModelAttributeField>() {
public ModelAttributeField apply(ResolvedField input) {
return new ModelAttributeField(alternateTypeProvider.alternateFor(input.getType()), input.getName(), input, input);
}
};
}
private Predicate<ResolvedField> publicFields() {
return new Predicate<ResolvedField>() {
public boolean apply(ResolvedField input) {
return input.isPublic();
}
};
}
private Predicate<Parameter> voidParameters() {
return new Predicate<Parameter>() {
public boolean apply(Parameter input) {
return Types.isVoid((ResolvedType) input.getType().orNull());
}
};
}
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, ExpansionContext context, 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, determineScalarParameterType(context.getOperationContext().consumes(), context.getOperationContext().httpMethod()), new ModelAttributeParameterMetadataAccessor(each.annotatedElements(), each.getFieldType(), each.getName()), context.getDocumentationContext().getDocumentationType(), new ParameterBuilder());
return this.pluginsManager.expandParameter(parameterExpansionContext);
}
private 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;
}
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 CustomizeModelAttributeParameterExpander.this.enumTypeDeterminer.isEnum(input.getFieldType().getErasedType());
}
};
}
private Predicate<ModelAttributeField> belongsToJavaPackage() {
return new Predicate<ModelAttributeField>() {
public boolean apply(ModelAttributeField input) {
return ClassUtils.getPackageName(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.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>() {
public ModelAttributeField apply(ResolvedMethod input) {
String name = ((PropertyDescriptor) propertyLookupByGetter.get(input.getRawMember())).getName();
return new ModelAttributeField(CustomizeModelAttributeParameterExpander.this.fieldType(alternateTypeProvider, input), name, input, (ResolvedMember) fieldsByName.get(name));
}
};
}
private Predicate<ResolvedMethod> onlyValidGetters(final Set<Method> methods) {
return new Predicate<ResolvedMethod>() {
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 (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, ResolvedMethod method) {
return alternateTypeProvider.alternateFor(method.getType());
}
private Set<PropertyDescriptor> propertyDescriptors(Class<?> clazz) {
try {
Set<PropertyDescriptor> result = new LinkedHashSet<>();
ImmutableSet<PropertyDescriptor> propertyDescriptors = FluentIterable.from(this.getBeanInfo(clazz).getPropertyDescriptors()).toSet();
propertyDescriptors.iterator();
for (PropertyDescriptor psd : propertyDescriptors) {
Field field = FieldUtils.getDeclaredField(clazz, psd.getName(), true);
if (field != null) {
field.setAccessible(true);
SwaggerIgnoreParameter ignoreSwaggerParameter = field.getDeclaredAnnotation(SwaggerIgnoreParameter.class);
if (ignoreSwaggerParameter == null) {
// 这个注解不存在才加入到最终的result中
result.add(psd);
}
}
}
return result;
} catch (IntrospectionException var3) {
LOG.warn(String.format("Failed to get bean properties on (%s)", clazz), var3);
return Sets.newHashSet();
}
}
private Map<Method, PropertyDescriptor> propertyDescriptorsByMethod(final Class<?> clazz, Set<PropertyDescriptor> propertyDescriptors) {
return FluentIterable.from(propertyDescriptors).filter(new Predicate<PropertyDescriptor>() {
public boolean apply(PropertyDescriptor input) {
return input.getReadMethod() != null && !clazz.isAssignableFrom(Collection.class) && !"isEmpty".equals(input.getReadMethod().getName());
}
}).uniqueIndex(new Function<PropertyDescriptor, Method>() {
public Method apply(PropertyDescriptor input) {
return input.getReadMethod();
}
});
}
@VisibleForTesting
BeanInfo getBeanInfo(Class<?> clazz) throws IntrospectionException {
return Introspector.getBeanInfo(clazz);
}
}
第三步:
在实体类属性上添加 @SwaggerIgnoreParameter即可
@ApiModel("拼团查询Dto")
@Data
@ToString
public class GroupQueryDto extends RequestDto {
private static final long serialVersionUID = 1741697867574442799L;
@ApiModelProperty(value = "拼团名称", dataType = "String")
private String groupName;
@ApiModelProperty(value = "店铺名称", dataType = "String")
private String storeName;
@SwaggerIgnoreParameter
@ApiModelProperty(value = "是否是拼团管理列表")
private boolean isManage;
}