Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring4 MVC Controller Pageable not working

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.

like image 785
smallufo Avatar asked Dec 25 '15 02:12

smallufo


1 Answers

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]

like image 66
Omkar Puttagunta Avatar answered Oct 05 '22 20:10

Omkar Puttagunta