10

I want Spring auto build Pageable object in controller . So I define :

@RequestMapping("/list")
public String list(Model model , Pageable pageable) {
  logger.info("pageable = {}" , pageable);
  // ... skipped
}

And I define PageableHandlerMethodArgumentResolver in the WebMvcConfigurerAdapter :

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
    resolver.setMaxPageSize(10);
    resolver.setOneIndexedParameters(true);
    argumentResolvers.add(resolver);
  }
}

I override page size to 10 (default is 20) , and set to 1-based paging. When running the page . I see the log :

Controller - pageable = Page request [number: 0, size 10, sort: null]

If I add parameter '?page=1&size=1' to the URL , it still prints :

Controller - pageable = Page request [number: 0, size 10, sort: null]

If I change parameter to ?sort=id , it logs :

Controller - pageable = Page request [number: 0, size 10, sort: id: ASC]

It seems my default size (10) is working , and sort parameter is correctly passed to Pageable . But why parameter page and size not working here ?

In PageableHandlerMethodArgumentResolver source code , it designates

private static final String DEFAULT_PAGE_PARAMETER = "page";
private static final String DEFAULT_SIZE_PARAMETER = "size";

But I don't know why it still not works. Did I miss anything ?

Environments:

spring-boot 1.3.1.RELEASE
spring-webmvc 4.2.3.RELEASE

========= Updated =========

Thanks @TimeTravel's answer.

It seems there's no way to define an 1-based & size is truly 10 (not minus one = 9) Pageable object here .

The correct solution is still pending... (except manually creation)

========= Updated Again =========

It seems it is the bug of spring-data-jpa:1.9.0.RELEASE . After upgrading to spring-data-jpa:1.9.2.RELEASE , it works now.

See DATACMNS-761 for detail.

smallufo
  • 11,516
  • 20
  • 73
  • 111

1 Answers1

10

You have to call the super class addArgumentResolvers method with your argumentResolvers as the argument.

 super.addArgumentResolvers(argumentResolvers);

Check the code below.

@Override
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
    resolver.setMaxPageSize(10);
    resolver.setOneIndexedParameters(true);
    argumentResolvers.add(resolver);
    super.addArgumentResolvers(argumentResolvers);
  }

Since you did set resolver.setOneIndexedParameters(true);, your page number will start with 0. So if you set the page=1 in the URL, the pageable object will have number=0. If you set it to false or remove that statement, then the size=1 in URL will have number=1 in pageable object.

From the documentation - protected boolean isOneIndexedParameters()

Indicates whether to expose and assume 1-based page number indexes in the request parameters. Defaults to false, meaning a page number of 0 in the request equals the first page. If this is set to true, a page number of 1 in the request will be considered the first page.

With the above two changes in place -

page=1&sort=id&size=1 will return [number: 1, size 1, sort: id: ASC]

Dariusz Bacinski
  • 8,324
  • 9
  • 38
  • 47
Omkar Puttagunta
  • 4,036
  • 3
  • 22
  • 35
  • 1
    Thanks it works. BTW , I find `resolver.setOneIndexedParameters(true);` also affects the size , which is very strange. For example , if `&size=10` , it logs 'size 9' . If I didn't set it true , size is correctly passed. – smallufo Dec 25 '15 at 11:27
  • Yes..your are correct about `resolver.setOneIndexedParameters(true);` This is because it assumes that the page number starts with `0`, the size will be decremented by 1. – Omkar Puttagunta Dec 25 '15 at 11:32
  • I think size shouldn't be affected by 1-based or 0-based paging, which is very counter intuitive . – smallufo Dec 25 '15 at 12:00
  • BTW , There seems no way to define an `1-based` & `size` is truly 10 (not minus one = 9) Pageable object here ? – smallufo Dec 28 '15 at 16:36