swagger2隐藏在API文档显示某些参数
有时候,利用swagger2建立API文档时,有些参数是需要隐藏在API文档显示,在方法中,参数的名字前加上
@ApiIgnore 就可以了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@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<MerchantOtherVdo> 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 解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
package com.example.swagger; import com.example.annotation.IgnoreSwaggerParameter; import com.fasterxml.classmate.ResolvedType; import com.fasterxml.classmate.members.ResolvedField; import com.google测试数据mon.annotations.VisibleForTesting; import com.google测试数据mon.base.Function; import com.google测试数据mon.base.Optional; import com.google测试数据mon.base.Predicate; import com.google测试数据mon.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测试数据mon.base.Objects.equal; import static com.google测试数据mon.base.Predicates.*; import static com.google测试数据mon.base.Strings.isNullOrEmpty; import static com.google测试数据mon.collect.FluentIterable.from; import static com.google测试数据mon.collect.Lists.newArrayList; import static com.google测试数据mon.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()); 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 解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
package com.zihuiinfo.facesdk.framework测试数据mon.swagger; import com.fasterxml.classmate.ResolvedType; import com.fasterxml.classmate.members.ResolvedField; import com.fasterxml.classmate.members.ResolvedMethod; import com.google测试数据mon.annotations.VisibleForTesting; import com.google测试数据mon.base.Function; import com.google测试数据mon.base.Optional; import com.google测试数据mon.base.Predicate; import com.google测试数据mon.collect.FluentIterable; import com.google测试数据mon.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测试数据mon.base.Objects.equal; import static com.google测试数据mon.base.Predicates.*; import static com.google测试数据mon.base.Strings.isNullOrEmpty; import static com.google测试数据mon.collect.FluentIterable.from; import static com.google测试数据mon.collect.Lists.newArrayList; import static com.google测试数据mon.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) { // 增加逻辑,忽略@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<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注解
1 2 3 4 5 6 7 8 9 10 11 |
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注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
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<Role> roles; } |
这样就可以自定义隐藏swagger2页面中的参数了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
原文链接:https://blog.csdn.net/tan_yh/article/details/103790796
查看更多关于swagger2隐藏在API文档显示某些参数的操作的详细内容...