我使用 spring-data-rest 和
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。
您知道任何其他解决方案或未来有类似的计划吗?
我使用 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;
}
}
您可以将自己的方法添加到 Repository 接口,并且返回类型为
List<DomainObject>
或 Collection<DomainObject>
并且没有 Pageable
参数。这将导致使用非寻呼响应。然后,您可以将旧客户端指向这些方法而不是默认方法。
或者,您可以将默认页面大小配置为非常大。将
spring.data.rest.default-page-size
设置为 application.properties
。
这不是最干净的解决方案,但以下代码允许您将
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);
}
}
评分最高的答案表示
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;
}
}
你可以这样实现:
@Configuration
@RequiredArgsConstructor
public class PageableHandlerConfiguration {
private final PageableHandlerMethodArgumentResolver resolver;
@PostConstruct
private void configurePageableResolver() {
resolver.setFallbackPageable(Pageable.unpaged());
}
}
现在,如果您没有在请求中传递可分页参数,您将得到未分页的结果。