Вот мое расширение на двух предыдущих примерах.Он также включает значения аннотаций ApiParam и настраивается с помощью параметров SpringDataWebProperties.
До расширения поля:
После расширения поля:
Существует несколько способов использования Swagger AlternateTypeRules.Они могут быть добавлены непосредственно в Swagger Docket, добавлены в виде bean-компонента несколькими способами.Вдохновленный приведенными выше примерами, вот как я это сделал, используя Annotation Proxy (см. Ниже) для включения дополнительных данных ApiParam:
@EnableSwagger2
@Configuration
public class SwaggerConfiguration {
@Bean
public AlternateTypeRuleConvention springDataWebPropertiesConvention(final SpringDataWebProperties webProperties) {
return new AlternateTypeRuleConvention() {
@Override
public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; }
@Override
public List<AlternateTypeRule> rules() {
return singletonList(
newRule(Pageable.class, pageableDocumentedType(webProperties.getPageable(), webProperties.getSort()))
);
}
};
}
private Type pageableDocumentedType(SpringDataWebProperties.Pageable pageable, SpringDataWebProperties.Sort sort) {
final String firstPage = pageable.isOneIndexedParameters() ? "1" : "0";
return new AlternateTypeBuilder()
.fullyQualifiedClassName(fullyQualifiedName(Pageable.class))
.property(property(pageable.getPageParameter(), Integer.class, ImmutableMap.of(
"value", "Page " + (pageable.isOneIndexedParameters() ? "Number" : "Index"),
"defaultValue", firstPage,
"allowableValues", String.format("range[%s, %s]", firstPage, Integer.MAX_VALUE),
"example", firstPage
)))
.property(property(pageable.getSizeParameter(), Integer.class, ImmutableMap.of(
"value", "Page Size",
"defaultValue", String.valueOf(pageable.getDefaultPageSize()),
"allowableValues", String.format("range[1, %s]", pageable.getMaxPageSize()),
"example", "5"
)))
.property(property(sort.getSortParameter(), String[].class, ImmutableMap.of(
"value", "Page Multi-Sort: fieldName,(asc|desc)"
)))
.build();
}
private String fullyQualifiedName(Class<?> convertedClass) {
return String.format("%s.generated.%s", convertedClass.getPackage().getName(), convertedClass.getSimpleName());
}
private AlternateTypePropertyBuilder property(String name, Class<?> type, Map<String, Object> parameters) {
return new AlternateTypePropertyBuilder()
.withName(name)
.withType(type)
.withCanRead(true)
.withCanWrite(true)
.withAnnotations(Collections.singletonList(AnnotationProxy.of(ApiParam.class, parameters)));
}
}
Для добавления дополнительных данных, таких как defaultValue и allowableValues, у вас естьиспользовать метод .withAnnotations()
, который требует прокси аннотации.Есть несколько доступных, вот мой (используя ломбок):
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Accessors(fluent = true)
public class AnnotationProxy implements Annotation, InvocationHandler {
@Getter
private final Class<? extends Annotation> annotationType;
private final Map<String, Object> values;
public static <A extends Annotation> A of(Class<A> annotation, Map<String, Object> values) {
return (A) Proxy.newProxyInstance(annotation.getClassLoader(),
new Class[]{annotation},
new AnnotationProxy(annotation, new HashMap<String, Object>(values) {{
put("annotationType", annotation); // Required because getDefaultValue() returns null for this call
}}));
}
public Object invoke(Object proxy, Method method, Object[] args) {
return values.getOrDefault(method.getName(), method.getDefaultValue());
}
}