Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring RestTemplate with paginated API

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

like image 232
turgos Avatar asked Jan 07 '16 04:01

turgos


1 Answers

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<>());     } } 
like image 93
장재훈 Avatar answered Sep 17 '22 13:09

장재훈