Pregunta

Using Spring Data REST with JPA in version 2.1.0.

How can I configure the pagination in order to have the page argument starting at index 1 instead of 0 ?

I have tried setting a custom HateoasPageableHandlerMethodArgumentResolver with an mvc:argument-resolvers, but that doesn't work:

<mvc:annotation-driven>
  <mvc:argument-resolvers>
      <bean class="org.springframework.data.web.HateoasPageableHandlerMethodArgumentResolver">
          <property name="oneIndexedParameters" value="true"/>
      </bean>
  </mvc:argument-resolvers>
</mvc:annotation-driven>

Note that this behaviour is perfectly coherent with the documentation for mvc:argument-resolver that says:

Using this option does not override the built-in support for resolving handler method arguments. To customize the built-in support for argument resolution configure RequestMappingHandlerAdapter directly.

But how can I achieve this ? If possible, in a clean and elegant way ?

¿Fue útil?

Solución 3

I use to do it using a customizer, which is something that they keep adding for more and more components with every new version:

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

You can put this in any @Configuration class, but ideally you should put it (with any other customization) in one that implements RepositoryRestConfigurer.

Otros consejos

The easiest way to do so is to subclass RepositoryRestMvcConfiguration and include your class into your configuration:

class CustomRestMvcConfiguration extends RepositoryRestMvcConfiguration {

  @Override
  @Bean
  public HateoasPageableHandlerMethodArgumentResolver pageableResolver() {

    HateoasPageableHandlerMethodArgumentResolver resolver = super.pageableResolver();
    resolver.setOneIndexedParameters(true);
    return resolver;
  }
}

In your XML configuration, replace:

<bean class="….RepositoryRestMvcConfiguration" />

with

<bean class="….CustomRestMvcConfiguration" />

or import the custom class instead of the standard one in your JavaConfig file.

I have configured the RequestMappingHandlerAdapter using a BeanPostProcessor, however I believe that's neither clean, nor elegant. That looks more like a hack. There must be a better way ! I'm giving the code below just for reference.

public class RequestMappingHandlerAdapterCustomizer implements BeanPostProcessor {

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof RequestMappingHandlerAdapter) {
              RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter)bean;
              List<HandlerMethodArgumentResolver> customArgumentResolvers = adapter.getCustomArgumentResolvers();
              if(customArgumentResolvers != null) {
                  for(HandlerMethodArgumentResolver customArgumentResolver : customArgumentResolvers) {
                      if(customArgumentResolver instanceof HateoasPageableHandlerMethodArgumentResolver) {
                          HateoasPageableHandlerMethodArgumentResolver hateoasPageableHandlerMethodArgumentResolver = (HateoasPageableHandlerMethodArgumentResolver)customArgumentResolver;
                          hateoasPageableHandlerMethodArgumentResolver.setOneIndexedParameters(true);
                      }
                  }
              }
        }
        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }   

}

<beans ...>
  <bean class="util.spring.beanpostprocessors.RequestMappingHandlerAdapterCustomizer" />
</beans>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top