swagger2隐藏在API文档显示某些参数的操作

swagger2隐藏在API文档显示某些参数 有时候,利用swagger2建立API文档时,有些参数是需要隐藏在API文档显示,在方法中,参数的名字前加上
@ApiIgnore 就可以了:

@PostMapping("modi/certificate")@ApiResponses({@ApiResponse(code = 0, message = "请求成功"),@ApiResponse(code = 10031, message = "商家的营业执照已经存在,不能重复入驻")})@ApiOperation(value = "https://www.it610.com/article/修改商家证照资料", notes = "修改商家证照资料", response = MerchantExtendVdo.class)@ApiImplicitParams({@ApiImplicitParam(name = "merchantExtendVdo", value = "https://www.it610.com/article/商铺对象", required = true, dataType = "MerchantExtendVdo"),@ApiImplicitParam(name = "merchantProvepicVdo", value = "https://www.it610.com/article/商铺证明图片", required = false, dataType = "MerchantProvepicVdo"),@ApiImplicitParam(name = "merchantOtherVdoList", value = "https://www.it610.com/article/商家的其他资质图片对象,List数组形式", required = false, dataType = "MerchantOtherVdo", allowMultiple = true, paramType = "body")})public ResultData modiCertificate(@MultiRequestBody @ApiIgnore MerchantExtendVdo merchantExtendVdo,@MultiRequestBody @ApiIgnore MerchantProvepicVdo merchantProvepicVdo,@MultiRequestBody @ApiIgnore List merchantOtherVdoList) {String accessToken = getAccessToken(); ResultData rd = storeService.modiCertificate(accessToken, merchantProvepicVdo, merchantOtherVdoList, merchantExtendVdo); return rd; }

swagger2自定义隐藏实体类属性 问题:
假如接收参数的实体类中关联了其他对象,那么swagger2的页面中参数应该会多出来这些,dept.id,dept.deptName,或者集合属性,roles[0].id,roles[0].roleName等等。
???这些属性有可能是不需要用来接收参数的,出现在文档中会给前端开发人员带来困惑
swagger2隐藏在API文档显示某些参数的操作
文章图片

笔者在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@Primarypublic class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander { private static final Logger LOG = LoggerFactory.getLogger(CustomizeModelAttributeParameterExpander.class); private final FieldProvider fieldProvider; private final EnumTypeDeterminer enumTypeDeterminer; @Autowiredpublic CustomizeModelAttributeParameterExpander(FieldProvider fields, EnumTypeDeterminer enumTypeDeterminer) {super(fields, enumTypeDeterminer); this.fieldProvider = fields; this.enumTypeDeterminer = enumTypeDeterminer; } @Overridepublic List expand(ExpansionContext context) { List parameters = newArrayList(); Set beanPropNames = getBeanPropertyNames(context.getParamType().getErasedType()); Iterable fields = FluentIterable.from(fieldProvider.in(context.getParamType())).filter(onlyBeanProperties(beanPropNames)); LOG.debug("Expanding parameter type: {}", context.getParamType()); AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider(); FluentIterable modelAttributes = from(fields).transform(toModelAttributeField(alternateTypeProvider)); FluentIterable 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 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 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 recursiveCollectionItemType(final ResolvedType paramType) {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return equal(collectionElementType(input.getFieldType()), paramType); }}; } private Predicate hiddenParameters() {return new Predicate() {@Overridepublic 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 recursiveType(final ExpansionContext context) {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return context.hasSeenType(input.getFieldType()); }}; } private Predicate simpleType() {return and(not(isCollection()), not(isMap()),or(belongsToJavaPackage(),isBaseType(),isEnum())); } private Predicate isCollection() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return isContainerType(input.getFieldType()); }}; } private Predicate isMap() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return Maps.isMapType(input.getFieldType()); }}; } private Predicate isEnum() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType()); }}; } private Predicate belongsToJavaPackage() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith("java.lang"); }}; } private Predicate isBaseType() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return Types.isBaseType(input.getFieldType())|| input.getField().getType().isPrimitive(); }}; } private Function toModelAttributeField(final AlternateTypeProvideralternateTypeProvider) {return new Function() {@Overridepublic ModelAttributeField apply(ResolvedField input) {return new ModelAttributeField(fieldType(alternateTypeProvider, input), input); }}; } private Predicate onlyBeanProperties(final Set beanPropNames) {return new Predicate() {@Overridepublic 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 getBeanPropertyNames(final Class clazz) { try {Set beanProps = new HashSet(); PropertyDescriptor[] propDescriptors = getBeanInfo(clazz).getPropertyDescriptors(); for (PropertyDescriptor propDescriptor : propDescriptors) { // 增加逻辑,忽略@IgnoreSwaggerParameter注解的字段Field field = clazz.getDeclaredField(propDescriptor.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(); } @VisibleForTestingBeanInfo 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@Primarypublic 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; @Autowiredprotected DocumentationPluginsManager pluginsManager; @Autowiredpublic CustomizeModelAttributeParameterExpander(FieldProvider fields, AccessorsProvider accessors, EnumTypeDeterminer enumTypeDeterminer) {super(fields, accessors, enumTypeDeterminer); this.fields = fields; this.accessors = accessors; this.enumTypeDeterminer = enumTypeDeterminer; }public List expand(ExpansionContext context) {List parameters = newArrayList(); Set propertyDescriptors = propertyDescriptors(context.getParamType().getErasedType()); Map propertyLookupByGetter= propertyDescriptorsByMethod(context.getParamType().getErasedType(), propertyDescriptors); Iterable getters = FluentIterable.from(accessors.in(context.getParamType())).filter(onlyValidGetters(propertyLookupByGetter.keySet())); Map fieldsByName = FluentIterable.from(this.fields.in(context.getParamType())).uniqueIndex(new Function() {@Overridepublic String apply(ResolvedField input) {return input.getName(); }}); LOG.debug("Expanding parameter type: {}", context.getParamType()); final AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider(); FluentIterable attributes =allModelAttributes(propertyLookupByGetter,getters,fieldsByName,alternateTypeProvider); FluentIterable 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 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 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 allModelAttributes(Map propertyLookupByGetter,Iterable getters,Map fieldsByName,AlternateTypeProvider alternateTypeProvider) {FluentIterable modelAttributesFromGetters = from(getters).transform(toModelAttributeField(fieldsByName, propertyLookupByGetter, alternateTypeProvider)); FluentIterable modelAttributesFromFields = from(fieldsByName.values()).filter(publicFields()).transform(toModelAttributeField(alternateTypeProvider)); return FluentIterable.from(Sets.union(modelAttributesFromFields.toSet(),modelAttributesFromGetters.toSet())); }private Function toModelAttributeField(final AlternateTypeProvider alternateTypeProvider) {return new Function() {@Overridepublic ModelAttributeField apply(ResolvedField input) {return new ModelAttributeField(alternateTypeProvider.alternateFor(input.getType()),input.getName(),input,input); }}; }private Predicate publicFields() {return new Predicate() {@Overridepublic boolean apply(ResolvedField input) {return input.isPublic(); }}; }private Predicate voidParameters() {return new Predicate() {@Overridepublic boolean apply(Parameter input) {return isVoid(input.getType().orNull()); }}; }private Predicate recursiveCollectionItemType(final ResolvedType paramType) {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return equal(collectionElementType(input.getFieldType()), paramType); }}; }private Predicate hiddenParameters() {return new Predicate() {@Overridepublic 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 recursiveType(final ExpansionContext context) {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return context.hasSeenType(input.getFieldType()); }}; }private Predicate simpleType() {return and(not(isCollection()), not(isMap()),or(belongsToJavaPackage(),isBaseType(),isEnum())); }private Predicate isCollection() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return isContainerType(input.getFieldType()); }}; }private Predicate isMap() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return Maps.isMapType(input.getFieldType()); }}; }private Predicate isEnum() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType()); }}; }private Predicate belongsToJavaPackage() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith("java.lang"); }}; }private Predicate isBaseType() {return new Predicate() {@Overridepublic boolean apply(ModelAttributeField input) {return Types.isBaseType(input.getFieldType())|| input.getFieldType().isPrimitive(); }}; }private Function toModelAttributeField(final Map fieldsByName,final Map propertyLookupByGetter,final AlternateTypeProvider alternateTypeProvider) {return new Function() {@Overridepublic ModelAttributeField apply(ResolvedMethod input) {String name = propertyLookupByGetter.get(input.getRawMember()).getName(); return new ModelAttributeField(fieldType(alternateTypeProvider, input),name,input,fieldsByName.get(name)); }}; }private Predicate onlyValidGetters(final Set methods) {return new Predicate() {@Overridepublic 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 propertyDescriptors(final Class clazz) {try {Set beanProps = new HashSet<>(); PropertyDescriptor[] descriptors = getBeanInfo(clazz).getPropertyDescriptors(); for (PropertyDescriptor descriptor : descriptors) {// 增加逻辑,忽略@IgnoreSwaggerParameter注解的字段Field field = null; try {field = clazz.getDeclaredField(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 propertyDescriptorsByMethod(final Class clazz,Set propertyDescriptors) {return FluentIterable.from(propertyDescriptors).filter(new Predicate() {@Overridepublic boolean apply(PropertyDescriptor input) {return input.getReadMethod() != null&& !clazz.isAssignableFrom(Collection.class)&& !"isEmpty".equals(input.getReadMethod().getName()); }}).uniqueIndex(new Function() {@Overridepublic Method apply(PropertyDescriptor input) {return input.getReadMethod(); }}); }@VisibleForTestingBeanInfo getBeanInfo(Class clazz) throws IntrospectionException {return Introspector.getBeanInfo(clazz); }public static String determineScalarParameterType(Set 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 = "https://www.it610.com/article/用户")public class User extends BaseModel { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "https://www.it610.com/article/用户id")private Integer id; @ApiModelProperty(value = "https://www.it610.com/article/用户名")private String username; @ApiModelProperty(value = "https://www.it610.com/article/密码")private String password; @ApiModelProperty(value = "https://www.it610.com/article/邮箱")private String email; @ApiModelProperty(value = "https://www.it610.com/article/昵称")private String nickname; @ApiModelProperty(value = "https://www.it610.com/article/生日")private Date birth; @ApiModelProperty(value="https://www.it610.com/article/登录时间")private Timestamp logintime; @ApiModelProperty(value = "https://www.it610.com/article/部门id")private Integer deptId; @ApiModelProperty(value = "https://www.it610.com/article/部门信息")@IgnoreSwaggerParameter // 在不需要递归展开的属性上加上IgnoreSwaggerParameter注解private Dept dept; @ApiModelProperty(value = "https://www.it610.com/article/角色信息")@IgnoreSwaggerParameterprivate List roles; }

这样就可以自定义隐藏swagger2页面中的参数了。
【swagger2隐藏在API文档显示某些参数的操作】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读