Spring RestTemplate with paginated API

spring boot pagination and sorting example
pagination rest api java example
spring boot pagination example mkyong
how to implement pagination in java
spring boot pagination and filter
spring mvc pagination example mkyong
rest api pagination tutorial
rest api pagination example

Our REST APIs are returning results in Pages. Here is an example of one Controller

@RequestMapping(value = "/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
@ResponseStatus(HttpStatus.OK)
public Page<MyObject> findAll(Pageable pageable) {
  ...
}

Is there an easy way to consume that API with RestTemplate?

if we do

ParameterizedTypeReference<Page<MyObject>> responseType = new ParameterizedTypeReference<Page<MyObject>>() { };

ResponseEntity<Page<MyObject>> result = restTemplate.exchange(url, HttpMethod.GET, null/*httpEntity*/, responseType);

List<MyObject> searchResult = result.getBody().getContent();

it throws an exception

org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not construct instance of org.springframework.data.domain.Page, 
problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information at [Source: java.io.PushbackInputStream@3be1e1f2; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.springframework.data.domain.Page, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information

Thank you in advance

When migrating from Spring Boot 1.x to 2.0, changed the code reading the Rest API response as

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.List;

public class RestPageImpl<T> extends PageImpl<T>{

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public RestPageImpl(@JsonProperty("content") List<T> content,
                        @JsonProperty("number") int number,
                        @JsonProperty("size") int size,
                        @JsonProperty("totalElements") Long totalElements,
                        @JsonProperty("pageable") JsonNode pageable,
                        @JsonProperty("last") boolean last,
                        @JsonProperty("totalPages") int totalPages,
                        @JsonProperty("sort") JsonNode sort,
                        @JsonProperty("first") boolean first,
                        @JsonProperty("numberOfElements") int numberOfElements) {

        super(content, PageRequest.of(number, size), totalElements);
    }

    public RestPageImpl(List<T> content, Pageable pageable, long total) {
        super(content, pageable, total);
    }

    public RestPageImpl(List<T> content) {
        super(content);
    }

    public RestPageImpl() {
        super(new ArrayList<>());
    }
}

Spring RestTemplate with paginated API - spring - html, When migrating from Spring Boot 1.x to 2.0, changed the code reading the Rest API response as import com.fasterxml.jackson.annotation.JsonCreator; import  All Implemented Interfaces: RestOperations. public class RestTemplate extends InterceptingHttpAccessor implements RestOperations Synchronous client to perform HTTP requests, exposing a simple, template method API over underlying HTTP client libraries such as the JDK HttpURLConnection, Apache HttpComponents, and others.

Changed the code reading the Rest API response as;

ParameterizedTypeReference<RestResponsePage<MyObject>> responseType = new ParameterizedTypeReference<RestResponsePage<MyObject>>() { };

ResponseEntity<RestResponsePage<MyObject>> result = restTemplate.exchange(url, HttpMethod.GET, null/*httpEntity*/, responseType);

List<MyObject> searchResult = result.getBody().getContent();

And here is the class I created for RestResponsePage

package com.basf.gb.cube.seq.vaadinui.util;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

public class RestResponsePage<T> extends PageImpl<T>{

  private static final long serialVersionUID = 3248189030448292002L;

  public RestResponsePage(List<T> content, Pageable pageable, long total) {
    super(content, pageable, total);
    // TODO Auto-generated constructor stub
  }

  public RestResponsePage(List<T> content) {
    super(content);
    // TODO Auto-generated constructor stub
  }

  /* PageImpl does not have an empty constructor and this was causing an issue for RestTemplate to cast the Rest API response
   * back to Page.
   */
  public RestResponsePage() {
    super(new ArrayList<T>());
  }

} 

REST Pagination in Spring, 1. Overview. This tutorial will focus on the implementation of pagination in a REST API, using Spring MVC and Spring Data. Spring Data REST Pagination. In Spring Data, if we need to return a few results from the complete data set, we can use any Pageable repository method, as it will always return a Page. The results will be returned based on the page number, page size, and sorting direction. Spring Data REST automatically recognizes URL parameters like page,

Expanding on above, but without the need to implement every property.

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.List;

public class RestPageImpl<T> extends PageImpl<T>{

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public RestPageImpl(@JsonProperty("content") List<T> content,
                        @JsonProperty("number") int page,
                        @JsonProperty("size") int size,
                        @JsonProperty("totalElements") long total) {
        super(content, new PageRequest(page, size), total);
    }

    public RestPageImpl(List<T> content, Pageable pageable, long total) {
        super(content, pageable, total);
    }

    public RestPageImpl(List<T> content) {
        super(content);
    }

    public RestPageImpl() {
        super(new ArrayList());
    }
}

REST Pagination in Spring, OK) public Page<MyObject> findAll(Pageable pageable) { } Is there an easy way to consume that API with RestTemplate? if we do What Is Spring REST Template? Spring RestTemplate class is a part of the spring-web which was introduced in Spring 3. RestTemplate class provides a very convenient way to test the HTTP based restful web services by providing overloaded methods for HTTP methods like GET, POST, PUT, DELETE, etc. Spring framework is also open-source.

There is no need in implementing a Page. You just have to use a PagedResources<T> as a type in your ParameterizedTypeReference.

So if your service returns response similar to (objects are removed for brevity):

{
    "_embedded": {
        "events": [
            {...},
            {...},
            {...},
            {...},
            {...}
        ]
    },
    "_links": {
        "first": {...},
         "self": {...},
         "next": {...},
         "last": {...}
    },
    "page": {
        "size": 5,
        "totalElements": 30,
        "totalPages": 6,
        "number": 0
    }
}

And the objects you care are of type Event then you should execute the request like:

ResponseEntity<PagedResources<Event>> eventsResponse = restTemplate.exchange(uriBuilder.build(true).toUri(),
                HttpMethod.GET, null, new ParameterizedTypeReference<PagedResources<Event>>() {});

If you get hold of the resources like:

PagedResources<Event> eventsResources = eventsResponse.getBody();

you will be able to access the page metadata (what you get in the "page" section), the links ("_links" section) and the content:

Collection<Event> eventsCollection = eventsResources.getContent();

Spring boot pagination and sorting example, Withing the scope of pagination, satisfying the HATEOAS constraint of REST means enabling the client of the API to discover the next and  The RestTemplate is the central class within the Spring framework for executing synchronous HTTP requests on the client side. Like Spring JdbcTemplate, RestTemplate is also a high-level API, which in turn is based on an HTTP client.

I had to make a small change so it would ignore the unknown property of empty that seems to have been recently introduced.

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class RestResponsePage<T> extends PageImpl<T> {
    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public RestResponsePage(@JsonProperty("content") List<T> content,
                            @JsonProperty("number") int number,
                            @JsonProperty("size") int size,
                            @JsonProperty("totalElements") Long totalElements,
                            @JsonProperty("pageable") JsonNode pageable,
                            @JsonProperty("last") boolean last,
                            @JsonProperty("totalPages") int totalPages,
                            @JsonProperty("sort") JsonNode sort,
                            @JsonProperty("first") boolean first,
                            @JsonProperty("numberOfElements") int numberOfElements) {

        super(content, PageRequest.of(number, size), totalElements);
    }

    public RestResponsePage(List<T> content, Pageable pageable, long total) {
        super(content, pageable, total);
    }

    public RestResponsePage(List<T> content) {
        super(content);
    }

    public RestResponsePage() {
        super(new ArrayList<>());
    }
}

REST Pagination in Spring, If any API supports paging and sorting, ALWAYS provide default values to its parameters – to be used when client does not choose specify any paging or sorting  4. Spring RestTemplate – HTTP PUT Method Example. Supported methods are: put(url, request) – PUTs the given request object to URL. REST API Code. Spring REST API for HTTP PUT method.

Spring Data JPA Tutorial: Pagination, Withing the scope of pagination, satisfying the HATEOAS constraint of REST means enabling the client of the API to discover the next and  In this tutorial, we're going to illustrate the broad range of operations where the Spring REST Client – RestTemplate – can be used, and used well. For the API side of all examples, we'll be running the RESTful service from here. How to do Basic Authentication with the Spring RestTemplate. How to set up Digest Authentication for the Spring

brunolellis/spring-rest-pagination: Spring REST and , This blog post describes how you can paginate your query results with Creating Database Queries With the JPA Criteria API describes how  A more useful way to consume a REST web service is programmatically. To help you with that task, Spring provides a convenient template class called RestTemplate. RestTemplate makes interacting with most RESTful services a one-line incantation. And it can even bind that data to custom domain types. First,

Java Code Examples org.springframework.web.client.RestTemplate, Spring REST Pagination example. This is a basic Spring application using pagination and REST API. Compile and run your project using mvn spring-boot:​run  Previous Next In this tutorial, we will see how to create rest client using Spring RestTemplate. We have already seen Spring restful web services crud example. We have used postman utility to demonstrate all HTTP methods such as get, post, delete and put but if you want to write java code for restful client , you can use Spring RestTemplate.

Comments
  • @All - Can anyone please guide here: stackoverflow.com/questions/59104894/… ?
  • This works for everything but the sort field, did anyone figure out how to deserialize and store that also?
  • why pass in null httpEntity? null /*httpEntity*/
  • This does not return the correct number of pages or total number of results.
  • @turgos - How can we make this working with Spring HATEOAS? With PagedResourcesAssembler ?
  • I tried this, but it throws com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException if Spring hands you back a JSON structure that includes "first" or other field not named in the constructor.
  • When following this the content is accessable but my metadata is always null. Though iterating over the Page is not possible because I can't get the number of total elements. Did someone else got this example working? I expect the content of this request to be a List<String> This is my code: ResponseEntity<PagedResources<String>> response = restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity, new ParameterizedTypeReference<PagedResources<String>>() {});
  • @Vladimir - Could you please guide me here: stackoverflow.com/questions/59104894/… ?
  • @Vladimir - These solution not working with PagedResourcesAssembler ?
  • This only handles the case for a 1-arg constructor. If you had a 3-arg constructor, then this is of no use.
  • other fields are not populated with above code except totalElements and content.