Spring pagination does not work

2019-09-14 04:43发布

问题:

Controller:

@RestController
@RequestMapping("/api")
public class TestResource {

    @RequestMapping(value="/test",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<Integer>> test(Pageable pageable) {
        List<Integer> init = new ArrayList<>(Arrays.asList(new Integer[]{1,2,3,4,5,6,7,8,9,10}));
        return ResponseEntity.ok(new PageImpl<>(init, pageable, init.size()).getContent());
    }
}

Request /api/test?page=1&size=2 returns entire init list (from 1 to 10).
From logs:

Enter: com.test.rest.TestResource.test() with argument[s] = [Page request [number: 1, size 2, sort: null]]

How to make it work?

回答1:

As I understood, Page works with repositories only, so I found a solution:

Use org.springframework.beans.support.PagedListHolder

public ResponseEntity<List<Integer>> getIntegers(Pageable pageable) {
    List<Integer> init = new ArrayList<>(Arrays.asList(new Integer[]{1,2,3,4,5,6,7,8,9,10}));
    PagedListHolder<Integer> holder = new PagedListHolder<>(init);
    holder.setPage(pageable.getPageNumber());
    holder.setPageSize(pageable.getPageSize());
    return ResponseEntity.ok(holder.getPageList());
}

Request /api/test?page=1&size=2 returns [3,4]



回答2:

Let's break down your calls.

  1. new PageImpl<>(init, pageable, init.size()

PageImpl's Constructor

public PageImpl(List<T> content, Pageable pageable, long total) {
    // PageImpl subclasses Chunk
    super(content, pageable);
    ...
}

Chunk's Constructor

public Chunk(List<T> content, Pageable pageable) {
    Assert.notNull(content, "Content must not be null!");

    this.content.addAll(content);
    this.pageable = pageable;
}
  1. PageImpl::getContent()

PageImpl doesn't implement this method, but Chunk does.

public List<T> getContent() {
    return Collections.unmodifiableList(content);
}

In summary, you set the value of content when you passed in init as a parameter to the constructor. When you called getContent(), you get more-or-less exactly what you put in originally.