[SPRING] Spring RestTemplate을 사용하여 페이지 <Entity> 응답을 소비하는 방법
SPRINGSpring RestTemplate을 사용하여 페이지 응답을 소비하는 방법
나는 스프링 데이터 (mongoDb)를 사용하고 있으며 저장소를 가지고있다 :
public interface StoriesRepository extends PagingAndSortingRepository<Story, String> {}
그럼 나는 컨트롤러가 :
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Page<StoryResponse>> getStories(Pageable pageable) {
Page<StoryResponse> stories = storiesRepository.findAll(pageable).map(StoryResponseMapper::toStoryResponse);
return ResponseEntity.ok(stories);
}
모든 것은 정상적으로 작동하지만 RestTemplate getForEntity 메소드를 사용하여 엔드 포인트를 소비 할 수 없습니다.
def entity = restTemplate.getForEntity(getLocalhost("/story"), new TypeReference<Page<StoryResponse>>(){}.class)
내 페이지 엔티티를 성공적으로 deserialize하기 위해 어떤 클래스를 제공해야합니까?
해결법
-
==============================
1.
new TypeReference<Page<StoryResponse>>() {}
이 문장의 문제점은 Jackson이 추상 형식을 인스턴스화 할 수 없다는 것입니다. Jackson에게 구체적인 유형으로 페이지를 인스턴스화하는 방법에 대한 정보를 제공해야합니다. 그러나 구체적인 유형 인 PageImpl에는 기본 생성자 또는 해당 @JsonCreators가 없으므로 다음 코드를 사용할 수 없습니다.
new TypeReference<PageImpl<StoryResponse>>() {}
필요한 정보를 Page 클래스에 추가 할 수 없기 때문에이 대답과 같이 기본 no-arg 생성자가있는 Page 인터페이스에 대한 사용자 정의 구현을 만드는 것이 좋습니다. 그런 다음 다음과 같이 유형 참조에서 해당 사용자 정의 구현을 사용하십시오.
new TypeReference<CustomPageImpl<StoryResponse>>() {}
다음은 링크 된 질문에서 복사 한 맞춤 구현입니다.
public class CustomPageImpl<T> extends PageImpl<T> { 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<T> 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<T> getContent() { return content; } public void setContent(List<T> content) { this.content = content; } @Override public Sort getSort() { return sort; } public void setSort(Sort sort) { this.sort = sort; } public Page<T> pageImpl() { return new PageImpl<>(getContent(), new PageRequest(getNumber(), getSize(), getSort()), getTotalElements()); } }
-
==============================
2.나는이 쓰레드가 조금 오래되었음을 알고 있지만, 누군가는 이것으로부터 이익을 얻길 바랍니다.
나는이 쓰레드가 조금 오래되었음을 알고 있지만, 누군가는 이것으로부터 이익을 얻길 바랍니다.
@Ali Dehghani의 답변은 좋은데, PageImpl
이 이미 수행 한 것을 다시 구현한다는 점만 다릅니다. 나는 이것을 오히려 불필요하다고 생각했다. PageImpl 을 확장하고 @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<HelperModel> { @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<HelperModel> content, @JsonProperty("number") int number, @JsonProperty("size") int size, @JsonProperty("totalElements") Long totalElements) { super(content, new PageRequest(number, size), totalElements); } }
그때:
HelperPage page = restTemplate.getForObject(url, HelperPage.class);
이는 CustomPageImpl
클래스를 만드는 것과 동일하지만 이미 PageImpl 에있는 모든 코드를 활용할 수 있습니다. -
==============================
3.언급 한 "경로 찾기"에서 RestTemplate의 교환 방법을 사용할 수 있습니다. 그러나 ParameterizedTypeReference
> ()를 전달하는 대신 ParameterizedTypeReference > ()를 전달해야합니다. 응답을 받으면 콘텐츠 (Collection )를 검색 할 수 있습니다. 언급 한 "경로 찾기"에서 RestTemplate의 교환 방법을 사용할 수 있습니다. 그러나 ParameterizedTypeReference
> ()를 전달하는 대신 ParameterizedTypeReference > ()를 전달해야합니다. 응답을 받으면 콘텐츠 (Collection )를 검색 할 수 있습니다. 코드는 다음과 같아야합니다.
ResponseEntity<PagedResources<StoryResponse>> response = restTemplate.exchange(getLocalhost("/story"), HttpMethod.GET, null, new ParameterizedTypeReference<PagedResources<StoryResponse>>() {}); PagedResources<StoryResponse> storiesResources = response.getBody(); Collection<StoryResponse> stories = storiesResources.getContent();
content storiesResources는 페이지 메타 데이터와 링크도 보유하고 있습니다.
자세한 단계별 설명은 https://stackoverflow.com/a/46847429/8805916에서 확인할 수 있습니다.
-
==============================
4.나는 스프링 라이브러리를 1. *로 다운 그레이드하고, 2를 사용하지 않도록 할 수있다. PageImpl을 확장하지 않는 Page에 대한 고유 한 코드를 만들어야했습니다.
나는 스프링 라이브러리를 1. *로 다운 그레이드하고, 2를 사용하지 않도록 할 수있다. PageImpl을 확장하지 않는 Page에 대한 고유 한 코드를 만들어야했습니다.
-
==============================
5.이 스레드를보고이 대답을 시도한다면 https://stackoverflow.com/a/44895867/8268335
이 스레드를보고이 대답을 시도한다면 https://stackoverflow.com/a/44895867/8268335
당신은 2 번째 문제를 만날 것입니다 :
Can not construct instance of org.springframework.data.domain.Pageable
그런 다음 여기에서 완벽한 솔루션을 찾습니다. https://stackoverflow.com/a/42002709/8268335
위의 대답과 문제 해결에서 클래스 RestPageImpl을 만듭니다.
-
==============================
6.당신은 아마 restTemplate의 exchange 메소드를 사용하고 그것으로부터 몸체를 얻을 수 있습니다 ..
당신은 아마 restTemplate의 exchange 메소드를 사용하고 그것으로부터 몸체를 얻을 수 있습니다 ..
다음 답변 (https://stackoverflow.com/a/31947188/3800576)을 확인하십시오. 이것은 당신을 도울지도 모른다.
-
==============================
7.@ResponseBody 주석을 추가 할 수 있습니다.
@ResponseBody 주석을 추가 할 수 있습니다.
@RequestMapping(method = RequestMethod.GET) @ResponseBody public ResponseEntity<Page<StoryResponse>> getStories(@RequestBody Pageable pageable) { Page<StoryResponse> stories = storiesRepository.findAll(pageable).map(StoryResponseMapper::toStoryResponse); return ResponseEntity.ok(stories); }
from https://stackoverflow.com/questions/34099559/how-to-consume-pageentity-response-using-spring-resttemplate by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring JpaRepository - 엔티티 분리 및 연결 (0) | 2019.01.02 |
---|---|
[SPRING] Spring 데이터 JPA : query ManyToMany (0) | 2019.01.02 |
[SPRING] Spring 프레임 워크 4.x와 Hibernate 5.2 통합하기 (0) | 2019.01.02 |
[SPRING] RestTemplate에서 응답 헤더를 읽으려면 어떻게해야합니까? (0) | 2019.01.02 |
[SPRING] 추상 수퍼 클래스에서 스프링 의존성 주입 (0) | 2019.01.02 |