可分页在招摇中未正确显示

Posted

技术标签:

【中文标题】可分页在招摇中未正确显示【英文标题】:pageble is not showing correctly in swagger 【发布时间】:2018-06-04 08:58:37 【问题描述】:

当我使用 Spring Boot 将 swagger 更新为 swagger2 时,它停止显示 pageable 类型的正确参数,而当它应该显示 pagesize 时,它开始显示 pageSizepageNumber,这不是在其余方面正确。

我没有手动更改任何内容,但由于某种原因,它显示了错误的参数名称。

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

而 pom 是

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


【问题讨论】:

请发布您的代码,以便其他人可以帮助调试它。 我已经更新了描述请检查@Helen 这有帮助吗? -- Swagger documentation for Spring Pageable interface 这是一个不同的问题,之前已修复,但现在不同了。我得到了参数,但出于某种原因使用了不同的名称 【参考方案1】:

https://github.com/springfox/springfox/issues/755#issuecomment-393378205

以下是创建规则的示例,该规则自动提供配置 Pageable 类型的约定。

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

【讨论】:

成功了,谢谢!我只需要在 rules() 方法中将“newRule”更改为“new AlternateTypeRule”(是一个构造函数)。 我看到了很多非常棒的实现......对我来说这是一个很好的解决方案,谢谢! 这对我有用,但为了支持多条件排序,我不得不将 String.class, "sort" 替换为 String[].class, "sort"【参考方案2】:

这是我对前两个示例的扩展。它还包括 ApiParam 注释值,可通过 SpringDataWebProperties 设置进行配置。

字段扩展前:

字段扩展后:

有几种方法可以使用 Swagger AlternateTypeRules。它们可以直接添加到 Swagger Docket 中,以多种方式添加为 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)));
    

为了添加像 defaultValue 和 allowableValues 这样的附加数据,你必须使用 .withAnnotations() 方法,它需要一个注解代理。有几个可用的,这是我的(使用 lombok):

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

【讨论】:

【参考方案3】:

升级到 springfox 2.9.0 后我看到了相同的行为,而没有更改任何代码。看来springfox在Spring控制器方法中遇到Pageable接口作为请求参数时,正在将pageSize,pageNumber和offset添加到Swagger文档中。

【讨论】:

【参考方案4】:

下面是我的 Swagger 配置类,它工作正常。

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

【讨论】:

以上是关于可分页在招摇中未正确显示的主要内容,如果未能解决你的问题,请参考以下文章

如何让分页在 WordPress 中为 get_posts() 工作?

ui-bootstrap 分页在初始化时重置当前页面

分页在php中无法正常工作

分页在角度 7 中不起作用。(我使用角度材料)

bootstrap分页与翻页

Fit项目分页组件的编写