[spring-projects/spring-boot]使用 Spring Data REST 时,spring.data.rest。必须使用properties而不是spring.data.web.pageable。和 spring.data.web.sort.*

2018-09-11 335 views

回答

4

感谢您的报告,但我不确定您的分析是否正确。被它PageableHandlerMethodArgumentResolverCustomizer消耗,通过它被注释org.springframework.data.web.config.SpringDataWebConfiguration导入。我不确定这是否相关。当然,我可能是错的。@EnableSpringDataWebConfigurationSpringDataWebAutoConfigurationRepositoryRestMvcAutoConfiguration

听起来您面临的问题是配置spring.data.web.pageable不起作用。您能否提供一个重现该问题的最小样本?这将使我们能够准确找出原因,并确信我们正在解决您遇到的问题。

5

我通过调试发现,SpringDataWebConfiguration中该 private @Autowired Optional<PageableHandlerMethodArgumentResolverCustomizer> pageableResolverCustomizer; 值为null,没有注入成功,以后可以写单元测试

6

我稍后可以写一个单元测试

谢谢。无论是单元测试还是重现问题的小样本都将为我们提供在这方面取得进展所需的信息。

6

参考你提供的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`

https://github.com/jimlgx/spring-boot-demo/blob/master/src/test/java/com/example/springbootdemo/SpringDataWebTest.java

3

再次感谢。我现在可以看到问题所在了。这确实是由于RespositoryRestMvcAutoConfiguration和之间的一些相互作用造成的,SpringDataWebAutoConfiguration但解决方案并不像颠倒它们的顺序那么简单。

我们当前的测试通过了,因为它是SpringDataWebAutoConfiguration单独测试的。它正在测试 Spring Data REST 不在类路径上的场景。如果 Spring Data REST 位于类路径上,则RespositoryRestMvcAutoConfiguration开始发挥作用。当它在 之前时SpringDataWebAutoConfigurationSpringDataWebAutoConfiguration由于它以由( 的导入)PageableHandlerMethodArgumentResolver定义的缺失为条件而后退。这种后退意味着自定义分页和排序的 Bean 会丢失。我相信我们还失去了一些通过 导入的其他功能。如果顺序颠倒并先行,则几个 Bean 会被覆盖,导致 master 上出现故障,其中不再允许 Bean 覆盖。RepositoryRestMvcConfigurationRespositoryRestMvcAutoConfiguration@EnableSpringDataWebSupportSpringDataWebAutoConfiguration

SpringDataWebAutoConfiguration退缩时,我们会失去它@EnableSpringDataWebSupport而转而支持RepositoryRestMvcConfiguration.是其中一些导入RepositoryRestMvcConfiguration的子类。我尚不清楚如何解决此问题,以便保留分页和排序的自定义,同时保留.HateoasAwareSpringDataWebConfiguration@EnableSpringDataWebSupport@EnableSpringDataWebSupport

2

由于 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 问题并将其转化为文档问题。

5
@Configuration
public class PageableConfig {

    @Bean
    PageableHandlerMethodArgumentResolverCustomizer pageableResolverCustomizer() {
        return pageableResolver -> pageableResolver.setOneIndexedParameters(true);
    }
}

会起作用的

5

我认为 SpringDataWebAutoConfiguration 应该删除 @ConditionalOnMissingBean(PageableHandlerMethodArgumentResolver.class) @wilkinsona

0

感谢您的建议,但我们不能这样做,因为它可能会导致多个PageableHandlerMethodArgumentResolverCustomizerbean,而 Spring Data 要求最多有一个(或一个@Primary)。

6

@All - 这个问题解决了吗?有什么更好的选择呢?

3

@JavaHelper 通过记录 Spring Data REST 的怪癖,我们已经在 Boot 中尽了一切努力。如果这个问题对您来说很重要,请投票或评论DATAREST-1290并让他们知道。

3
@Configuration
public class PageableConfig {

    @Bean
    PageableHandlerMethodArgumentResolverCustomizer pageableResolverCustomizer() {
        return pageableResolver -> pageableResolver.setOneIndexedParameters(true);
    }
}

这是最好的解决方案。

1

它也不起作用

5

它不工作

9

@gopalsingh462 如果您使用 Spring Data REST,这是可以预料的。上面对此进行了解释:

然后它们会立即根据RepositoryRestConfiguration.

请遵循以下建议:

简而言之,如果您使用 Spring Data REST 那么您需要使用属性spring.data.rest,如果您只是使用 Spring Data 的 Web 支持而没有 Spring Data REST,那么您需要使用属性spring.data.web.pageable。这并不理想,但考虑到 Spring Data 当前的架构,这是我们能做的最好的事情。

9

我不明白这个概念,你能简单地解释一下吗?我正在使用这些 import org.springframework.data.domain.Page;导入 org.springframework.data.domain.Pageable;导入 org.springframework.data.jpa.repository.JpaRepository;

6

我怀疑您没有使用 Spring Data REST,因此您应该在文件spring.data.web.pageable.one-indexed-parameters=true中进行设置application.properties

如果您还有任何疑问,请关注 Stack Overflow 或Gitter。正如贡献指南中提到的,我们更喜欢仅使用 GitHub 问题来解决错误和增强功能。