我们的REST API在Pages中返回结果.以下是一个Controller的示例
@RequestMapping(value = "/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8") @ResponseStatus(HttpStatus.OK) public PagefindAll(Pageable pageable) { ... }
有没有一种简单的方法来使用RestTemplate使用该API?
如果我们这样做
ParameterizedTypeReference> responseType = new ParameterizedTypeReference >() { }; ResponseEntity > result = restTemplate.exchange(url, HttpMethod.GET, null/*httpEntity*/, responseType); List searchResult = result.getBody().getContent();
它引发了一个例外
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
先感谢您
从Spring Boot 1.x迁移到2.0时,将读取Rest API响应的代码更改为
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 RestPageImplextends PageImpl { @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) public RestPageImpl(@JsonProperty("content") List 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 content, Pageable pageable, long total) { super(content, pageable, total); } public RestPageImpl(List content) { super(content); } public RestPageImpl() { super(new ArrayList<>()); } }
将读取Rest API响应的代码更改为;
ParameterizedTypeReference> responseType = new ParameterizedTypeReference >() { }; ResponseEntity > result = restTemplate.exchange(url, HttpMethod.GET, null/*httpEntity*/, responseType); List searchResult = result.getBody().getContent();
这是我为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 RestResponsePageextends PageImpl { private static final long serialVersionUID = 3248189030448292002L; public RestResponsePage(List content, Pageable pageable, long total) { super(content, pageable, total); // TODO Auto-generated constructor stub } public RestResponsePage(List 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 ()); } }
扩展上面,但不需要实现每个属性.
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 RestPageImplextends PageImpl { @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) public RestPageImpl(@JsonProperty("content") List content, @JsonProperty("number") int page, @JsonProperty("size") int size, @JsonProperty("totalElements") long total) { super(content, new PageRequest(page, size), total); } public RestPageImpl(List content, Pageable pageable, long total) { super(content, pageable, total); } public RestPageImpl(List content) { super(content); } public RestPageImpl() { super(new ArrayList()); } }