如何在 spring-data-rest 中禁用 JpaRepository 的分页

问题描述 投票:0回答:5

我使用

JpaRepository
来创建 Rest-Endpoints。默认情况下,所有
JpaRepository
都启用分页,这是一件好事。但我有一个遗留应用程序,我们将其移植到不支持分页的新堆栈中。我想根据 URL 参数禁用分页,以便仍然能够在新的应用程序代码中使用分页。

我尝试了各种方法来公开带分页和不带分页的资源:

  • 使用
    CrudRepository
    :导致只有一个未分页的端点,并且缺少方法
    flush
  • 重写我的存储库界面中的
    List<T> findAll()
    方法并用
    RestResource
    对其进行注释。我本以为该方法将作为搜索方法公开,但事实并非如此。
  • Page<T> findAll(Pageable pageable)
    注释
    @RestResource(exported=false)
    并注释
    List<T> findAll()
    ,如前面的项目符号所示。我希望这能取代默认方法。但这无论如何都不是有效的解决方案,因为只暴露了非分页端点。
  • 通过
    size=-1
    获得无限结果 -> 使用默认分页大小

我已经看到 spring-controller

RepositoryEntityController
使用
RepositoryInvoker
来调用存储库上的方法。
Pageable
使用
PageableHandlerMethodArgumentResolver
进行解析,它始终返回可分页(在查询中指定、带注释或默认可分页)。 目前我看到的唯一解决方案是实现一个自定义
PageableHandlerMethodArgumentResolver
,如果传递了自定义 url 参数,则返回 null。

您知道任何其他解决方案或未来有类似的计划吗?

pagination spring-data-rest
5个回答
11
投票

我使用 PagingAndSortingRepository 和此配置来设置我的 pageableResolver:

@Configuration
public class RestApiConfiguration extends RepositoryRestConfigurerAdapter {

    @Bean
    public HateoasPageableHandlerMethodArgumentResolver customResolver(
        HateoasPageableHandlerMethodArgumentResolver pageableResolver) {
        pageableResolver.setOneIndexedParameters(true);
        pageableResolver.setFallbackPageable(new PageRequest(0, Integer.MAX_VALUE));
        pageableResolver.setMaxPageSize(Integer.MAX_VALUE);
        return pageableResolver;
    }
}

参见:https://jira.spring.io/browse/DATACMNS-929

这样,如果请求中包含页面和大小,您将获得所请求的页面,但如果请求中不包含它们,您将获得所有记录。在这两种情况下,如果指定了排序,则用于对数据进行排序。 在第二种情况下,记录在页面内返回,但我可以接受。

编辑 https://jira.spring.io/browse/DATACMNS-929 已修复,因此在新版本中,您将能够使用

null
FallbackPageable 配置解析器。这样,当存在可分页数据(即
page
size
)时,您将检索一页,但当不存在时,您将检索所有记录:

@Configuration
public class RestApiConfiguration extends RepositoryRestConfigurerAdapter {

    @Bean
    public HateoasPageableHandlerMethodArgumentResolver customResolver(
        HateoasPageableHandlerMethodArgumentResolver pageableResolver) {
        pageableResolver.setOneIndexedParameters(true);
        pageableResolver.setFallbackPageable(null);
        return pageableResolver;
    }
}

4
投票

您可以将自己的方法添加到 Repository 接口,并且返回类型为

List<DomainObject>
Collection<DomainObject>
并且没有
Pageable
参数。这将导致使用非寻呼响应。然后,您可以将旧客户端指向这些方法而不是默认方法。

或者,您可以将默认页面大小配置为非常大。将

spring.data.rest.default-page-size
设置为
application.properties


3
投票

这不是最干净的解决方案,但以下代码允许您将

unpaged=true
作为查询参数传递,以便在一页中获取所有结果。

@Configuration
public class RestApiServletConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        PageableHandlerMethodArgumentResolver pageableResolver = new PageableHandlerMethodArgumentResolver() {
            @Override
            public Pageable resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
                if ("true".equals(webRequest.getParameter(getParameterNameToUse("unpaged", methodParameter)))) {
                    return Pageable.unpaged();
                }

                return super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
            }
        };
        resolvers.add(pageableResolver);
    }
}

2
投票

评分最高的答案表示

setFallbackPageable
为空,不再有效。使用
PageRequest
的默认静态构造函数,如下所示:

@Configuration
public class RestApiConfiguration extends RepositoryRestConfigurerAdapter {

    @Bean
    public HateoasPageableHandlerMethodArgumentResolver customResolver(
        HateoasPageableHandlerMethodArgumentResolver pageableResolver) {
        pageableResolver.setOneIndexedParameters(true);
        pageableResolver.setFallbackPageable(PageRequest.of(0, Integer.MAX_VALUE));
        pageableResolver.setMaxPageSize(Integer.MAX_VALUE);
        return pageableResolver;
    }
}

1
投票

你可以这样实现:

@Configuration
@RequiredArgsConstructor
public class PageableHandlerConfiguration {

    private final PageableHandlerMethodArgumentResolver resolver;

    @PostConstruct
    private void configurePageableResolver() {

        resolver.setFallbackPageable(Pageable.unpaged());
    }

}

现在,如果您没有在请求中传递可分页参数,您将得到未分页的结果。

© www.soinside.com 2019 - 2024. All rights reserved.