Describe the bug
Rest Controller in server with Spring Boot 2.7.18:
If I consume that end point from application with Spring Boot 2.7.18 (Cloud 2021.0.5) Deserialization is correct.
If I consume that end point from application with Spring Boot 3.2.4 (Cloud 2023.0.1) Deserialization fails.
log trace:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of org.springframework.cloud.openfeign.support.PageJacksonModule$SimplePageable (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('INSTANCE')
If I create Page object with the constructor:
Page
Works perfectly in Spring 2.7.18 and Spring boot 3.2.4
Thank you !!
Comment From: OlgaMaciaszek
Hello @dienarvil, thanks for reporting the issue. Please provide a minimal, complete, verifiable example that reproduces the issue.
Comment From: dienarvil
localhost:8080/testok -> feign call to ok end point with Page page = new PageImpl<>(build, PageRequest.of(0,2), 2);
and
localhost:8080/testko -> feign call to ko end point with Page
Comment From: ttddyy
I just stumbled upon the same symptom and dug in a bit.
The reported error happens when deserializing the following json:
{
"content": [
"foo"
],
"pageable": "INSTANCE", <== HERE
"totalPages": 1,
"totalElements": 1,
"last": true,
"size": 1,
"number": 0,
"sort": [],
"numberOfElements": 1,
"first": true,
"empty": false
}
As @dienarvil noted, the json is generated by the following:
Page<String> page = new PageImpl<>(List.of("foo")); // or usage of Pageable.unpaged()
String json = this.objectMapper.writeValueAsString(page);
// deserialize json will throw the exception
When serializing a PageImpl, if it doesn't specify the pageable parameter, it uses Pageable.unpaged().
SpringDataJacksonConfiguration from spring-data-commons registers a serializer for Unpaged which writes out the value INSTANCE. So, the generated json has pageable:"INSTANCE".
It is not the json format that spring-cloud-openfeign is expecting.
In v4.1.1, PageJacksonModule#SimplePageImpl added Pageable object parameter(https://github.com/spring-cloud/spring-cloud-openfeign/pull/984) and the expected format is SimplePageable. The deserializer doesn't work for INSTANCE string from Unpaged.
Per https://github.com/spring-projects/spring-data-commons/issues/3024, spring-data-commons v3.3 may produce a more stable json representation.
@dienarvil
For a fix, I suggest simply providing the page information(Pageable) rather than using Unpaged while creating PageImpl object. So, that the response json will be more conformed as an added benefit.
Comment From: dienarvil
@dienarvil For a fix, I suggest simply providing the page information(
Pageable) rather than usingUnpagedwhile creatingPageImplobject. So, that the response json will be more conformed as an added benefit.
Thanks for the advice, yeah, with "normal" pagination from a repository the problem will never arise.
Thanks again!!
Comment From: OlgaMaciaszek
Thanks for the analysis @ttddyy. Until this gets addressed better in Spring Data, we expect a proper Pageable object to be provided.