[spring-projects/spring-boot]使用 Spring Data REST 时,spring.data.rest。必须使用properties而不是spring.data.web.pageable。和 spring.data.web.sort.*
回答
感谢您的报告,但我不确定您的分析是否正确。被它PageableHandlerMethodArgumentResolverCustomizer
消耗,通过它被注释org.springframework.data.web.config.SpringDataWebConfiguration
导入。我不确定这是否相关。当然,我可能是错的。@EnableSpringDataWebConfiguration
SpringDataWebAutoConfiguration
RepositoryRestMvcAutoConfiguration
听起来您面临的问题是配置spring.data.web.pageable
不起作用。您能否提供一个重现该问题的最小样本?这将使我们能够准确找出原因,并确信我们正在解决您遇到的问题。
我通过调试发现,SpringDataWebConfiguration中该
private @Autowired Optional<PageableHandlerMethodArgumentResolverCustomizer> pageableResolverCustomizer;
值为null,没有注入成功,以后可以写单元测试
我稍后可以写一个单元测试
谢谢。无论是单元测试还是重现问题的小样本都将为我们提供在这方面取得进展所需的信息。
参考你提供的demo_public voidcustomizePageable()
我已经修改了请参考下面的单元测试来说明问题,希望对你有帮助
@RunWith(SpringRunner.class)
@SpringBootTest
@EnableConfigurationProperties(value = {SpringDataWebProperties.class})
public class SpringDataWebTest {
@Autowired
private ApplicationContext context;
@Autowired
private SpringDataWebProperties properties;
@Test
public void customizePageableWithConfig() {
PageableHandlerMethodArgumentResolver argumentResolver = this.context
.getBean(PageableHandlerMethodArgumentResolver.class);
// properties.pageable equal to properties config
assertThat(properties.getPageable().getPageParameter())
.isEqualTo("p");
assertThat(properties.getPageable().getSizeParameter())
.isEqualTo("s");
assertThat(properties.getPageable().isOneIndexedParameters())
.isEqualTo(true);
assertThat(properties.getPageable().getPrefix())
.isEqualTo("abc");
assertThat(properties.getPageable().getQualifierDelimiter())
.isEqualTo("__");
assertThat(properties.getPageable().getMaxPageSize())
.isEqualTo(100);
// properties.pageable not equal argumentResolver
assertThat(ReflectionTestUtils.getField(argumentResolver, "pageParameterName"))
.isNotEqualTo(properties.getPageable().getPageParameter());
assertThat(ReflectionTestUtils.getField(argumentResolver, "sizeParameterName"))
.isNotEqualTo(properties.getPageable().getSizeParameter());
assertThat(ReflectionTestUtils.getField(argumentResolver, "oneIndexedParameters"))
.isNotEqualTo(properties.getPageable().isOneIndexedParameters());
assertThat(ReflectionTestUtils.getField(argumentResolver, "prefix"))
.isNotEqualTo(properties.getPageable().getPrefix());
assertThat(ReflectionTestUtils.getField(argumentResolver, "qualifierDelimiter"))
.isNotEqualTo(properties.getPageable().getQualifierDelimiter());
assertThat(ReflectionTestUtils.getField(argumentResolver, "maxPageSize"))
.isNotEqualTo(properties.getPageable().getMaxPageSize());
}
spring.data.web.pageable.page-parameter=p
spring.data.web.pageable.size-parameter=s
spring.data.web.pageable.default-page-size=10
spring.data.web.pageable.prefix=abc
spring.data.web.pageable.qualifier-delimiter=__
spring.data.web.pageable.max-page-size=100
spring.data.web.pageable.one-indexed-parameters=true`
再次感谢。我现在可以看到问题所在了。这确实是由于RespositoryRestMvcAutoConfiguration
和之间的一些相互作用造成的,SpringDataWebAutoConfiguration
但解决方案并不像颠倒它们的顺序那么简单。
我们当前的测试通过了,因为它是SpringDataWebAutoConfiguration
单独测试的。它正在测试 Spring Data REST 不在类路径上的场景。如果 Spring Data REST 位于类路径上,则RespositoryRestMvcAutoConfiguration
开始发挥作用。当它在 之前时SpringDataWebAutoConfiguration
,SpringDataWebAutoConfiguration
由于它以由( 的导入)PageableHandlerMethodArgumentResolver
定义的缺失为条件而后退。这种后退意味着自定义分页和排序的 Bean 会丢失。我相信我们还失去了一些通过 导入的其他功能。如果顺序颠倒并先行,则几个 Bean 会被覆盖,导致 master 上出现故障,其中不再允许 Bean 覆盖。RepositoryRestMvcConfiguration
RespositoryRestMvcAutoConfiguration
@EnableSpringDataWebSupport
SpringDataWebAutoConfiguration
当SpringDataWebAutoConfiguration
退缩时,我们会失去它@EnableSpringDataWebSupport
而转而支持RepositoryRestMvcConfiguration
.是其中一些导入RepositoryRestMvcConfiguration
的子类。我尚不清楚如何解决此问题,以便保留分页和排序的自定义,同时保留.HateoasAwareSpringDataWebConfiguration
@EnableSpringDataWebSupport
@EnableSpringDataWebSupport
由于 Spring Data 的构造方式,不可能在 Spring Boot 中修复此问题。
如果您使用 Spring Data REST,则是将org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration.pageableResolver()
创建PageableHandlerMethodArgumentResolver
.它调用其 super 方法来创建和自定义解析器,该解析器使用PageableHandlerMethodArgumentResolverCustomizer
应用spring.data.web.pageable properties
.然后它们会立即根据RepositoryRestConfiguration
.在Spring Boot中,RepositoryRestConfiguration
可以使用spring.data.rest
属性进行定制。
简而言之,如果您使用 Spring Data REST 那么您需要使用属性spring.data.rest
,如果您只是使用 Spring Data 的 Web 支持而没有 Spring Data REST,那么您需要使用属性spring.data.web.pageable
。这并不理想,但考虑到 Spring Data 当前的架构,这是我们能做的最好的事情。
我认为我们应该打开一个 Spring Data 问题并将其转化为文档问题。
我已经打开DATAREST-1290。
@Configuration
public class PageableConfig {
@Bean
PageableHandlerMethodArgumentResolverCustomizer pageableResolverCustomizer() {
return pageableResolver -> pageableResolver.setOneIndexedParameters(true);
}
}
会起作用的
我认为 SpringDataWebAutoConfiguration 应该删除 @ConditionalOnMissingBean(PageableHandlerMethodArgumentResolver.class) @wilkinsona
感谢您的建议,但我们不能这样做,因为它可能会导致多个PageableHandlerMethodArgumentResolverCustomizer
bean,而 Spring Data 要求最多有一个(或一个@Primary
)。
@All - 这个问题解决了吗?有什么更好的选择呢?
@JavaHelper 通过记录 Spring Data REST 的怪癖,我们已经在 Boot 中尽了一切努力。如果这个问题对您来说很重要,请投票或评论DATAREST-1290并让他们知道。
@Configuration
public class PageableConfig {
@Bean
PageableHandlerMethodArgumentResolverCustomizer pageableResolverCustomizer() {
return pageableResolver -> pageableResolver.setOneIndexedParameters(true);
}
}
这是最好的解决方案。
它也不起作用
它不工作
@gopalsingh462 如果您使用 Spring Data REST,这是可以预料的。上面对此进行了解释:
然后它们会立即根据
RepositoryRestConfiguration
.
请遵循以下建议:
简而言之,如果您使用 Spring Data REST 那么您需要使用属性
spring.data.rest
,如果您只是使用 Spring Data 的 Web 支持而没有 Spring Data REST,那么您需要使用属性spring.data.web.pageable
。这并不理想,但考虑到 Spring Data 当前的架构,这是我们能做的最好的事情。
我不明白这个概念,你能简单地解释一下吗?我正在使用这些 import org.springframework.data.domain.Page;导入 org.springframework.data.domain.Pageable;导入 org.springframework.data.jpa.repository.JpaRepository;