当我更新招摇swagger2与我的春天启动它停止表示pageable
类型正确的参数时,它应该显示page
和size
而是开始呈现出pageSize
和pageNumber
这是不是在其余方面是正确的。
我没有手动更改任何东西,但由于某些原因,它显示了错误的参数名称。
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Rest API")
.securitySchemes(Collections.singletonList(new BasicAuth(BASIC_AUTH)))
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.paths(s -> oneOf(
"/some/**",
"/search-controller/**").test(s))
.build();
和聚甲醛是
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-data-rest</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.0</version>
</dependency>
和控制器是一样的东西下面
@RequestMapping(method = RequestMethod.GET)
public HttpEntity<?> findAll(@RequestParam(value = "countryIsoAlpha2", required = false) final String countryKey, final Pageable pageable){
}
https://github.com/springfox/springfox/issues/755#issuecomment-393378205
下面是用于创建一个规则,自动地提供用于配置可分页类型的公约的例子。
@Configuration
public class SwaggerConfig {
@Bean
public AlternateTypeRuleConvention pageableConvention(
final TypeResolver resolver) {
return new AlternateTypeRuleConvention() {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public List<AlternateTypeRule> rules() {
return Arrays.asList(
newRule(resolver.resolve(Pageable.class), resolver.resolve(pageableMixin()))
);
}
};
}
private Type pageableMixin() {
return new AlternateTypeBuilder()
.fullyQualifiedClassName(
String.format("%s.generated.%s",
Pageable.class.getPackage().getName(),
Pageable.class.getSimpleName()))
.withProperties(Arrays.asList(
property(Integer.class, "page"),
property(Integer.class, "size"),
property(String.class, "sort")
))
.build();
}
private AlternateTypePropertyBuilder property(Class<?> type, String name) {
return new AlternateTypePropertyBuilder()
.withName(name)
.withType(type)
.withCanRead(true)
.withCanWrite(true);
}
}
我升级到2.9.0 springfox无需更改任何代码后看到相同的行为。似乎springfox是增加的pageSize,PAGENUMBER并且当它遇到的可分页接口如在Spring控制器方法的请求参数中的偏移到扬鞭文档。
下面是我扬鞭配置类,它是工作的罚款。
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.archisoft.mtx.controller"))
.paths(regex("/api.*"))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo(
"Backend API Services",
"Backend APIs for Business to Business",
"V1.0",
"Terms of service",
"Sadun | Tharanga email",
"Archisoft Global",
"Archisoft URL");
return apiInfo;
}
@Bean
public AlternateTypeRuleConvention pageableConvention(
final TypeResolver resolver,
final RepositoryRestConfiguration restConfiguration) {
return new AlternateTypeRuleConvention() {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public List<AlternateTypeRule> rules() {
return singletonList(
newRule(resolver.resolve(Pageable.class), resolver.resolve(pageableMixin()))
);
}
};
}
private Type pageableMixin() {
return new AlternateTypeBuilder()
.fullyQualifiedClassName(
String.format("%s.generated.%s",
Pageable.class.getPackage().getName(),
Pageable.class.getSimpleName()))
.withProperties(Stream.of(
property(Integer.class, "page"),
property(Integer.class, "size"),
property(String.class, "sort")
).collect(toList()))
.build();
}
private AlternateTypePropertyBuilder property(Class<?> type, String name) {
return new AlternateTypePropertyBuilder()
.withName(name)
.withType(type)
.withCanRead(true)
.withCanWrite(true);
}
}
这是我在前面的两个例子扩张。它还包括ApiParam标注值,并通过SpringDataWebProperties设置中进行配置。
有几种方法可以采用扬鞭AlternateTypeRules。它们可以直接加入到扬鞭文案,添加在几个方面的bean。通过上面的例子启发,这里是我是如何做到的,使用(如下所示)的注释代理包括附加的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)));
}
}
为了增加像默认值和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());
}
}