1. 程式人生 > >通過Spring RestTemplate 做分頁

通過Spring RestTemplate 做分頁

資料查詢端:
Page<MyObject> hosts=service.listByXX(MyObject);
接收端:
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();

異常:

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

查了好久找到了解決方案:

總結下來,是三種方案:1、自定義接收資料模型(屬性要和page傳遞資料一致)

                                            2、自定義類實現Page介面

                                            3、自定義類繼承PageImpl類(此類為Page介面實現類)

程式碼:

1、自定義接收資料型別

public class PageResultModel<E> {

    private int number;

    private int size;

    private List<E> content;

    private boolean last;

    private int totalPages;

    private int totalElements;

    private Object sort;

    private boolean first;

    private int numberOfElements;

    private boolean next;

    private boolean previous;

    public int getNumber() {return number;}

    public void setNumber(int number) {this.number = number;}

    public int getTotalPages() {return totalPages;}

    public void setTotalPages(int totalPages) {this.totalPages = totalPages;}

    public int getNumberOfElements() {return numberOfElements;}

    public void setNumberOfElements(int numberOfElements) {this.numberOfElements = numberOfElements;}

    public boolean isFirst() {return first;}

    public void setFirst(boolean first) {this.first = first;}

    public int getTotalElements() {return totalElements;}

    public void setTotalElements(int totalElements) {this.totalElements = totalElements;}

    public Object getSort() {return sort;}

    public void setSort(Object sort) {this.sort = sort;}

    public boolean isLast() {return last;}

    public void setLast(boolean last) {this.last = last;}

    public int getSize() {return size;}

    public void setSize(int size) {this.size = size;}

    public List<E> getContent() {return content;}

    public void setContent(List<E> content) {this.content = content;}

    public boolean hasPrevious() {
        return previous;
    }

    public void setPrevious(boolean previous) {
        this.previous = previous;
    }

    public boolean hasNext() {
        return next;
    }

    public void setNext(boolean next) {
        this.next = next;
    }

}
第二種和第三種可以在這個網址看到:https://stackoverflow.com/questions/34647303/spring-resttemplate-with-paginated-api

ps:其實還有一個方法:把Page換成map,用map儲存必要資料然後返回,雖然很low的感覺,不過還是寫下來了
資料查詢端:
Page<MyObject> page=service.listByXX(myObject);

map.put("data",page.getContent);
map.put("totalSize",page.getTotalElements());
.....
接收的時候改成:
ParameterizedTypeReference<Map> responseType = new ParameterizedTypeReference<Map>() { };

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

Map searchResult = result.getBody();