Comment utiliser la réponse de la page à l’aide de Spring RestTemplate

J’utilise des données de spring (mongoDb) et j’ai mon référentiel:

public interface StoriesRepository extends PagingAndSortingRepository {} 

Alors j’ai un contrôleur:

 @RequestMapping(method = RequestMethod.GET) public ResponseEntity<Page> getStories(Pageable pageable) { Page stories = storiesRepository.findAll(pageable).map(StoryResponseMapper::toStoryResponse); return ResponseEntity.ok(stories); } 

Tout fonctionne bien, mais je ne peux pas utiliser mon sharepoint terminaison à l’aide de la méthode RestTemplate getForEntity:

 def entity = restTemplate.getForEntity(getLocalhost("/story"), new TypeReference<Page>(){}.class) 

Quelle classe dois-je fournir pour désérialiser avec succès ma page d’entités?

 new TypeReference>() {} 

Le problème avec cette déclaration est que Jackson ne peut pas instancier un type abstrait. Vous devez donner à Jackson les informations sur la façon d’instancier une Page avec un type concret. Mais son type concret, PageImpl , n’a aucun constructeur par défaut ni aucun @JsonCreator s, vous ne pouvez donc pas utiliser le code suivant:

 new TypeReference>() {} 

Comme vous ne pouvez pas append les informations requirejses à la classe Page , il est préférable de créer une implémentation personnalisée pour l’interface de Page qui a un constructeur par défaut sans argument, comme dans cette réponse . Ensuite, utilisez cette implémentation personnalisée dans la référence de type, comme suit:

 new TypeReference>() {} 

Voici l’implémentation personnalisée, copiée à partir d’une question liée:

 public class CustomPageImpl extends PageImpl { private static final long serialVersionUID = 1L; private int number; private int size; private int totalPages; private int numberOfElements; private long totalElements; private boolean previousPage; private boolean firstPage; private boolean nextPage; private boolean lastPage; private List content; private Sort sort; public CustomPageImpl() { super(new ArrayList<>()); } @Override public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } @Override public int getSize() { return size; } public void setSize(int size) { this.size = size; } @Override public int getTotalPages() { return totalPages; } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } @Override public int getNumberOfElements() { return numberOfElements; } public void setNumberOfElements(int numberOfElements) { this.numberOfElements = numberOfElements; } @Override public long getTotalElements() { return totalElements; } public void setTotalElements(long totalElements) { this.totalElements = totalElements; } public boolean isPreviousPage() { return previousPage; } public void setPreviousPage(boolean previousPage) { this.previousPage = previousPage; } public boolean isFirstPage() { return firstPage; } public void setFirstPage(boolean firstPage) { this.firstPage = firstPage; } public boolean isNextPage() { return nextPage; } public void setNextPage(boolean nextPage) { this.nextPage = nextPage; } public boolean isLastPage() { return lastPage; } public void setLastPage(boolean lastPage) { this.lastPage = lastPage; } @Override public List getContent() { return content; } public void setContent(List content) { this.content = content; } @Override public Sort getSort() { return sort; } public void setSort(Sort sort) { this.sort = sort; } public Page pageImpl() { return new PageImpl<>(getContent(), new PageRequest(getNumber(), getSize(), getSort()), getTotalElements()); } } 

Je sais que ce sujet est un peu ancien, mais j’espère que quelqu’un en profitera.

La réponse de @Ali Dehghani est bonne, sauf qu’elle ré-implémente ce que PageImpl a déjà fait. J’ai considéré que c’était plutôt inutile. J’ai trouvé une meilleure solution en créant une classe qui étend PageImpl et spécifie un constructeur @JsonCreator :

 import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.company.model.HelperModel; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import java.util.List; public class HelperPage extends PageImpl { @JsonCreator // Note: I don't need a sort, so I'm not including one here. // It shouldn't be too hard to add it in tho. public HelperPage(@JsonProperty("content") List content, @JsonProperty("number") int number, @JsonProperty("size") int size, @JsonProperty("totalElements") Long totalElements) { super(content, new PageRequest(number, size), totalElements); } } 

Alors:

 HelperPage page = restTemplate.getForObject(url, HelperPage.class); 

Cela revient à créer une CustomPageImpl mais nous permet de tirer parti de tout le code déjà PageImpl dans PageImpl .

En tant que “pathfinder” mentionné, vous pouvez utiliser la méthode d’ exchange de RestTemplate . Cependant, au lieu de passer ParameterizedTypeReference>() vous devez passer ParameterizedTypeReference>() . Lorsque vous obtenez la réponse, vous pouvez récupérer le contenu – Collection .

Le code devrait ressembler à ceci:

 ResponseEntity> response = restTemplate.exchange(getLocalhost("/story"), HttpMethod.GET, null, new ParameterizedTypeReference>() {}); PagedResources storiesResources = response.getBody(); Collection stories = storiesResources.getContent(); 

En plus du contenu storiesResources contient aussi des métadonnées de page et des liens.

Une explication plus détaillée est disponible ici: https://stackoverflow.com/a/46847429/8805916

Je ne peux que le faire rétrograder la bibliothèque Spring à 1. * et ne pas utiliser 2. * Je devais créer mon propre code pour la page qui n’allonge pas PageImpl

Vous pouvez probablement utiliser la méthode d’échange de restTemplate et en extraire le corps.

Consultez la réponse suivante https://stackoverflow.com/a/31947188/3800576 . Cela pourrait vous aider

Vous pouvez essayer d’append l’annotation @ResponseBody:

 @RequestMapping(method = RequestMethod.GET) @ResponseBody public ResponseEntity> getStories(@RequestBody Pageable pageable) { Page stories = storiesRepository.findAll(pageable).map(StoryResponseMapper::toStoryResponse); return ResponseEntity.ok(stories); }