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

网友投稿 316 2023-01-03

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

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

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

@ApiIgnore 就可以了:

@PostMapping("modi/certificate")

@ApiResponses({@ApiResponse(code = 0, message = "请求成功"),

@ApiResponse(code = 10031, message = "商家的营业执照已经存在,不能重复入驻")

})

@ApiOperation(value = "修改商家证照资料", notes = "修改商家证照资料", response = MerchantExtendVdo.class)

@ApiImplicitParams({

@ApiImplicitParam(name = "merchantExtendVdo", value = "商铺对象", required = true, dataType = "MerchantExtendVdo"),

@ApiImplicitParam(name = "merchantProvepicVdo", value = "商铺证明图片", required = false, dataType = "MerchantProvepicVdo"),

@ApiImplicitParam(name = "merchantOtherVdoList", value = "商家的其他资质图片对象,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提供的配置中没有找到隐藏此类参数的设置

解决

但是通过阅读源码找到了展开参数的类

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 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()),

rGjbilFe 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() {

@Override

public boolean apply(ModelAttributeField input) {

return equal(collectionElementType(input.getFieldType()), paramType);

}

};

}

private Predicate hiddenParameters() {

return new Predicate() {

@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 recursiveType(final ExpansionContext context) {

return new Predicate() {

@Override

public 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() {

@Override

public boolean apply(ModelAttributeField input) {

return isContainerType(input.getFieldType());

}

};

}

private Predicate isMap() {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return Maps.isMapType(input.getFieldType());

}

};

}

private Predicate isEnum() {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType());

}

};

}

private Predicate belongsToJavaPackage() {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith("java.lang");

}

};

}

private Predicate isBaseType() {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return Types.isBaseType(input.getFieldType())

|| input.getField().getType().isPrimitive();

}

};

}

private Function toModelAttributeField(

final AlternateTypeProvider

alternateTypeProvider) {

return new Function() {

@Override

public ModelAttributeField apply(ResolvedField input) {

return new ModelAttributeField(fieldType(alternateTypeProvider, input), input);

}

};

}

private Predicate onlyBeanProperties(final Set beanPropNames) {

return new Predicate() {

@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 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();

}

@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 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() {

@Override

public 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() {

@Override

public ModelAttributeField apply(ResolvedField input) {

return new ModelAttributeField(

alternateTypeProvider.alternateFor(input.getType()),

input.getName(),

input,

input);

}

};

}

private Predicate publicFields() {

return new Predicate() {

@Override

public boolean apply(ResolvedField input) {

return input.isPublic();

}

};

}

private Predicate voidParameters() {

return new Predicate() {

@Override

public boolean apply(Parameter input) {

return isVoid(input.getType().orNull());

}

};

}

private Predicate recursiveCollectionItemType(final ResolvedType paramType) {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return equal(collectionElementType(input.getFieldType()), paramType);

}

};

}

private Predicate hiddenParameters() {

return new Predicate() {

@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 recursiveType(final ExpansionContext context) {

return new Predicate() {

@Override

public 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() {

@Override

public boolean apply(ModelAttributeField input) {

return isContainerType(input.getFieldType());

}

};

}

private Predicate isMap() {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return Maps.isMapType(input.getFieldType());

}

};

}

private Predicate isEnum() {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType());

}

};

}

private Predicate belongsToJavaPackage() {

return new Predicate() {

@Override

public boolean apply(ModelAttributeField input) {

return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith("java.lang");

}

};

}

private Predicate isBaseType() {

return new Predicate() {

@Override

public 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() {

@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 onlyValidGetters(final Set methods) {

return new Predicate() {

@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 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() {

@Override

public boolean apply(PropertyDescriptor input) {

return input.getReadMethod() != null

&& !clazz.isAssignableFrom(Collection.class)

&& !"isEmpty".equals(input.getReadMethod().getName());

}

})

.uniqueIndex(new Function() {

@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;

@ApiModelProperty(value = "角色信息")

@IgnoreSwaggerParameter

private List roles;

}

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Springboot快速入门教程
下一篇:天天汇通快递物流查询单号(天天汇通快递物流查询单号)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~