4

I want to allow pagination in a REST API I am writing. I would like to send requests as follows

GET /people?page[number]=1page[size]=25

or maybe

GET /people?page.number=1page.size=25
  • The request above is just an example of what I am trying to do, if you know of a cleaner way to send the request please advise.

Then

@RequestMapping(value = "/people", params = { "page" })
public void findAll(@RequestParam("page") PaginationInformation paginationInformation) { 

}

PaginationInformation is just a plain old pojo with number and size getters and setters.

Is something like this possible in the latest version of Spring? I realise I can just pass pageNumber and pageSize and bind as integers but I would rather use and object as I want to also support filtering which will be much more complex.

jax
  • 37,735
  • 57
  • 182
  • 278

2 Answers2

9

You can bind request parameters to custom model objects in Spring like this:

public class Page {
    private int pageOffset;
    private int pageSize;

    // Getters and setters omitted
}

@RequestMapping("/people")
public void findAll(Page page) {
}

If you send request like GET /foo?pageOffset=0&pageSize=25 then the page parameter will be populated with those values. Notice also that there is no @RequestParam annotation.

Resolved Page object will be provided to the handler by ServletModelAttributeMethodProcessor under the hood, so feel free to look at its source code for more details.

If you need more flexibility in customizing the resolution of paging parameters, you can implement custom HandlerMethodArgumentResolver. You may use PageableHandlerMethodArgumentResolver from Spring Data JPA as an inspiration if you decide to go this way (or use Spring Data JPA for your persistence layer).

Bohuslav Burghardt
  • 33,626
  • 7
  • 114
  • 109
  • This looks good. So when I have a `FilterInformation` object I will be able to supply two or more objects right? `public void findAll(Page page, Filters filters, Sort sort)` and prefix all field inside the filter pojo with fitlerXXX. Does this sound correct? – jax Nov 08 '15 at 23:40
  • @jax Yup, that should work. But just to be clear you mention `FilterInformation` and then `Filters` in your comment. Is that supposed to be one and the same class or different classes? – Bohuslav Burghardt Nov 08 '15 at 23:45
  • Yeah sorry, they're the same. – jax Nov 08 '15 at 23:49
2

Bohuslav Burghardt explained in his answer the most easy way: using a command-object / form-backing-object to pick the two parameters. You explicit asked:

Is something like this possible in the latest version of Spring?

Because I think the command-object way is well known, you asked for an other, more powerfull, way. Yes there is one (it exist since Spring 3.1).

HandlerMethodArgumentResolver.

Because you have a special use case: Paging; I will not explain how exactly a HandlerMethodArgumentResolver needs to be developed. Instead I recommend you to have a look at:

(maybe this answer of mine helps you a bit in understanding how to deal with HandlerMethodArgumentResolver and how to register them)

So you can develop your own HandlerMethodArgumentResolver or just use PageableHandlerMethodArgumentResolver form spring-data.

Community
  • 1
  • 1
Ralph
  • 118,862
  • 56
  • 287
  • 383