2016-01-07 14 views
12

私たちのREST APIは結果をPagesに返します。ここに1つのコントローラの例がありますページ別APIを使用したSpring RestTemplate

RestTemplateでそのAPIを簡単に使用する方法はありますか?

我々は

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: [email protected]; 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 

答えて

6

としてのREST APIのレスポンスを読み込むコードを変更し、事前にありがとう投げます。

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(); 

そして、ここで私は、総要素が正しく設定されていなかったので、掲載ソリューションは、私のために動作しませんでした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>()); 
    } 

} 
+0

なぜヌルhttpEntityに渡し:Uは、(あなたが"page"セクションで何を得る)リンク("_links"節)とコンテンツをページ・メタデータにアクセスすることができるでしょうか? null/* httpEntity */ –

+0

これは、正しいページ数または結果の合計数を返しません。 – ACOMIT001

0

のために作成したクラスです。私は、私のために働いたデリゲートパターンでページを実装しました。ここに作業コードがあります:

import org.springframework.core.convert.converter.Converter; 
import org.springframework.data.domain.Page; 
import org.springframework.data.domain.PageImpl; 
import org.springframework.data.domain.Pageable; 
import org.springframework.data.domain.Sort; 

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

public class RestPage<T> implements Page<T> { 
    private PageImpl<T> pageDelegate = new PageImpl<>(new ArrayList<>(0)); 

    public List<T> getContent() { 
     return pageDelegate.getContent(); 
    } 

    public int getNumber() { 
     return pageDelegate.getNumber(); 
    } 

    public int getNumberOfElements() { 
     return pageDelegate.getNumberOfElements(); 
    } 

    public int getSize() { 
     return pageDelegate.getSize(); 
    } 

    public Sort getSort() { 
     return pageDelegate.getSort(); 
    } 

    public long getTotalElements() { 
     return pageDelegate.getTotalElements(); 
    } 

    public int getTotalPages() { 
     return pageDelegate.getTotalPages(); 
    } 

    public boolean hasContent() { 
     return pageDelegate.hasContent(); 
    } 

    public boolean hasNext() { 
     return pageDelegate.hasNext(); 
    } 

    public boolean hasPrevious() { 
     return pageDelegate.hasPrevious(); 
    } 

    public boolean isFirst() { 
     return pageDelegate.isFirst(); 
    } 

    public boolean isLast() { 
     return pageDelegate.isLast(); 
    } 

    public Iterator<T> iterator() { 
     return pageDelegate.iterator(); 
    } 

    public <S> Page<S> map(Converter<? super T, ? extends S> converter) { 
     return pageDelegate.map(converter); 
    } 

    public Pageable nextPageable() { 
     return pageDelegate.nextPageable(); 
    } 

    public Pageable previousPageable() { 
     return pageDelegate.previousPageable(); 
    } 

    public void setContent(List<T> content) { 
     pageDelegate = new PageImpl<>(content, null, getTotalElements()); 
    } 


    public void setTotalElements(int totalElements) { 
     pageDelegate = new PageImpl<>(getContent(), null, totalElements); 
    } 

    public String toString() { 
     return pageDelegate.toString(); 
    } 
} 
+0

これは、1引数のコンストラクタの場合のみ処理します。 3引数のコンストラクタがあれば、これは役に立たない。 – cst1992

+1

他のフィールドにはtotalElementsとコンテンツを除く上記のコードが設定されていません。 – MasterCode

6

すべてのプロパティを実装する必要はありません。

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()); 
    } 
} 
2

Pageを実装する必要はありません。 ParameterizedTypeReferenceには、タイプとしてPagedResources<T>を使用するだけです。

あなたのサービスが復帰すると(オブジェクトを簡潔にするため削除されている)のような応答のであれば:

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

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

そして、あなたが気にオブジェクトがタイプEventである、あなたは次のようにリクエストを実行する必要があります

次のようなリソースを取得した場合:

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

Collection<Event> eventsCollection = eventsResources.getContent(); 
関連する問題