swagger 2 API 문서 에 숨겨 진 매개 변 수 를 표시 하 는 동작
때때로 swagger 2 를 이용 하여 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<MerchantOtherVdo> merchantOtherVdoList) {
String accessToken = getAccessToken();
ResultData rd = storeService.modiCertificate(accessToken, merchantProvepicVdo, merchantOtherVdoList, merchantExtendVdo);
return rd;
}
swagger 2 사용자 정의 실체 클래스 속성 숨 기기질문:
만약 에 파 라 메 터 를 받 는 실체 클래스 에 다른 대상 이 연결 되 어 있다 면 swagger 2 페이지 의 매개 변 수 는 이러한 것,dept.id,dept.deptName 또는 집합 속성,roles[0].id,roles[0].roleName 등 이 많 을 것 입 니 다.
이 속성 들 은 인 자 를 받 을 필요 가 없 을 수도 있 습 니 다.문서 에 나타 나 면 전단 개발 자 들 에 게 곤 혹 스 러 움 을 줄 수 있 습 니 다.
필 자 는 swagger 2 가 제공 한 설정 에서 이러한 매개 변 수 를 숨 기 는 설정 을 찾 지 못 했 습 니 다.
해결 하 다.
하지만 원본 코드 를 읽 으 면서 매개 변 수 를 펼 치 는 종 류 를 찾 았 습 니 다.
springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander
필 자 는 이 종 류 를 계승 하여 첨가 하 였 다.
@Primary
주 해 는 원본 코드 의 논 리 를 덮어 쓰 고 수정 되 었 습 니 다.getBeanPropertyNames
방법swagger 2 버 전 2.8.0 솔 루 션
package com.example.swagger;
import com.example.annotation.IgnoreSwaggerParameter;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.members.ResolvedField;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.schema.Maps;
import springfox.documentation.schema.Types;
import springfox.documentation.schema.property.field.FieldProvider;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.schema.AlternateTypeProvider;
import springfox.documentation.spi.schema.EnumTypeDeterminer;
import springfox.documentation.spi.service.contexts.DocumentationContext;
import springfox.documentation.spi.service.contexts.ParameterExpansionContext;
import springfox.documentation.spring.web.readers.parameter.ExpansionContext;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeField;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Predicates.*;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static springfox.documentation.schema.Collections.collectionElementType;
import static springfox.documentation.schema.Collections.isContainerType;
import static springfox.documentation.schema.Types.typeNameFor;
/**
* {@link ModelAttributeParameterExpander}
* @see CustomizeModelAttributeParameterExpander#getBeanPropertyNames(Class)
* @see ModelAttributeParameterExpander#getBeanPropertyNames(Class)
* @see IgnoreSwaggerParameter
*/
@Component
@Primary
public class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander {
private static final Logger LOG = LoggerFactory.getLogger(CustomizeModelAttributeParameterExpander.class);
private final FieldProvider fieldProvider;
private final EnumTypeDeterminer enumTypeDeterminer;
@Autowired
public CustomizeModelAttributeParameterExpander(FieldProvider fields, EnumTypeDeterminer enumTypeDeterminer) {
super(fields, enumTypeDeterminer);
this.fieldProvider = fields;
this.enumTypeDeterminer = enumTypeDeterminer;
}
@Override
public List<Parameter> expand(ExpansionContext context) {
List<Parameter> parameters = newArrayList();
Set<String> beanPropNames = getBeanPropertyNames(context.getParamType().getErasedType());
Iterable<ResolvedField> fields = FluentIterable.from(fieldProvider.in(context.getParamType()))
.filter(onlyBeanProperties(beanPropNames));
LOG.debug("Expanding parameter type: {}", context.getParamType());
AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();
FluentIterable<ModelAttributeField> modelAttributes = from(fields)
.transform(toModelAttributeField(alternateTypeProvider));
FluentIterable<ModelAttributeField> expendables = modelAttributes
.filter(not(simpleType()))
.filter(not(recursiveType(context)));
for (ModelAttributeField each : expendables) {
LOG.debug("Attempting to expand expandable field: {}", each.getField());
parameters.addAll(
expand(
context.childContext(
nestedParentName(context.getParentName(), each.getField()),
each.getFieldType(),
context.getDocumentationContext())));
}
FluentIterable<ModelAttributeField> collectionTypes = modelAttributes
.filter(and(isCollection(), not(recursiveCollectionItemType(context.getParamType()))));
for (ModelAttributeField each : collectionTypes) {
LOG.debug("Attempting to expand collection/array field: {}", each.getField());
ResolvedType itemType = collectionElementType(each.getFieldType());
if (Types.isBaseType(itemType) || enumTypeDeterminer.isEnum(itemType.getErasedType())) {
parameters.add(simpleFields(context.getParentName(), context.getDocumentationContext(), each));
} else {
parameters.addAll(
expand(
context.childContext(
nestedParentName(context.getParentName(), each.getField()),
itemType,
context.getDocumentationContext())));
}
}
FluentIterable<ModelAttributeField> simpleFields = modelAttributes.filter(simpleType());
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);
}
}
swagger 2 버 전 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<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;
}
}
사용자 정의 Ignore SwaggerParamer 주 해 를 사 용 했 습 니 다.
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 {
}
사용 방식,재 귀적 으로 전개 할 필요 가 없 는 속성 에 Ignore SwaggerParameter 설명 을 추가 합 니 다.
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;
}
이렇게 하면 swagger 2 페이지 에 숨겨 진 인 자 를 사용자 정의 할 수 있 습 니 다.이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
studyphop 환경 소프트웨어 Nginx 는 index. php 와 Pathinfo 모드 설정 예 를 숨 깁 니 다.studyphop 환경 소프트웨어 Nginx 는 index. php 와 Pathinfo 모드 설정 예 를 숨 깁 니 다. 방법: nginx. cnf 파일 열기 다음 코드 바 꾸 기 실제 수 정 된 핵심 코드 는 다음...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.