From dec4d695a1dcf070f1315d6c89f4a529b1b9a15c Mon Sep 17 00:00:00 2001 From: weslyvinicius Date: Tue, 17 Feb 2026 14:07:18 +0000 Subject: [PATCH 1/2] Fix #1324: Add @JsonAlias support to SimplePageable for SNAKE_CASE compatibility Signed-off-by: weslyvinicius --- .../cloud/openfeign/support/PageJacksonModule.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/PageJacksonModule.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/PageJacksonModule.java index dc38c598b..cff84f68f 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/PageJacksonModule.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/PageJacksonModule.java @@ -242,8 +242,10 @@ static class SimplePageable implements Pageable { private final PageRequest delegate; - SimplePageable(@JsonProperty("pageNumber") int number, @JsonProperty("pageSize") int size, - @JsonProperty("sort") Sort sort) { + SimplePageable( + @JsonProperty("pageNumber") @JsonAlias({"page-number", "page_number", "pagenumber", "PageNumber"}) int number, + @JsonProperty("pageSize") @JsonAlias({"page-size", "page_size", "pagesize", "PageSize"}) int size, + @JsonProperty("sort") Sort sort) { delegate = buildPageRequest(number, size, sort); } From fe60c6b963ebef42e444c900b6d58f80e5060062 Mon Sep 17 00:00:00 2001 From: weslyvinicius Date: Tue, 17 Feb 2026 15:47:44 +0000 Subject: [PATCH 2/2] Add tests for pageable deserialization with various alias formats Signed-off-by: weslyvinicius --- .../support/PageJacksonModuleTests.java | 67 ++++++++++++++++ .../resources/withPageableAliasHyphen.json | 77 +++++++++++++++++++ .../resources/withPageableAliasLowercase.json | 72 +++++++++++++++++ .../withPageableAliasPascalCase.json | 77 +++++++++++++++++++ .../withPageableAliasUnderscore.json | 77 +++++++++++++++++++ 5 files changed, 370 insertions(+) create mode 100644 spring-cloud-openfeign-core/src/test/resources/withPageableAliasHyphen.json create mode 100644 spring-cloud-openfeign-core/src/test/resources/withPageableAliasLowercase.json create mode 100644 spring-cloud-openfeign-core/src/test/resources/withPageableAliasPascalCase.json create mode 100644 spring-cloud-openfeign-core/src/test/resources/withPageableAliasUnderscore.json diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/PageJacksonModuleTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/PageJacksonModuleTests.java index 635913d99..953d799b6 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/PageJacksonModuleTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/PageJacksonModuleTests.java @@ -188,4 +188,71 @@ void serializeAndDeserializeFilledMultipleCascade() throws JsonProcessingExcepti assertThat(cascadedResult.getPageable().getPageNumber()).isEqualTo(6); } + @Test + void deserializePageableWithHyphenatedAlias() { + // Given + File file = new File("./src/test/resources/withPageableAliasHyphen.json"); + // When + Page result = objectMapper.readValue(file, Page.class); + // Then + assertThat(result).isNotNull(); + assertThat(result.getTotalElements()).isEqualTo(15); + assertThat(result.getContent()).hasSize(10); + assertThat(result.getPageable()).isNotNull(); + assertThat(result.getPageable().getPageNumber()).isEqualTo(2); + assertThat(result.getPageable().getPageSize()).isEqualTo(3); + assertThat(result.getPageable().getSort().getOrderFor("firstName").getDirection()) + .isEqualTo(Sort.Direction.ASC); + } + + @Test + void deserializePageableWithUnderscoreAlias() { + // Given + File file = new File("./src/test/resources/withPageableAliasUnderscore.json"); + // When + Page result = objectMapper.readValue(file, Page.class); + // Then + assertThat(result).isNotNull(); + assertThat(result.getTotalElements()).isEqualTo(10); + assertThat(result.getContent()).hasSize(10); + assertThat(result.getPageable()).isNotNull(); + assertThat(result.getPageable().getPageNumber()).isEqualTo(1); + assertThat(result.getPageable().getPageSize()).isEqualTo(2); + assertThat(result.getPageable().getSort().getOrderFor("lastName").getDirection()) + .isEqualTo(Sort.Direction.DESC); + } + + @Test + void deserializePageableWithLowercaseAlias() { + // Given + File file = new File("./src/test/resources/withPageableAliasLowercase.json"); + // When + Page result = objectMapper.readValue(file, Page.class); + // Then + assertThat(result).isNotNull(); + assertThat(result.getTotalElements()).isEqualTo(8); + assertThat(result.getContent()).hasSize(10); + assertThat(result.getPageable()).isNotNull(); + assertThat(result.getPageable().getPageNumber()).isEqualTo(0); + assertThat(result.getPageable().getPageSize()).isEqualTo(4); + assertThat(result.getPageable().getSort()).isEqualTo(Sort.unsorted()); + } + + @Test + void deserializePageableWithPascalCaseAlias() { + // Given + File file = new File("./src/test/resources/withPageableAliasPascalCase.json"); + // When + Page result = objectMapper.readValue(file, Page.class); + // Then + assertThat(result).isNotNull(); + assertThat(result.getTotalElements()).isEqualTo(20); + assertThat(result.getContent()).hasSize(10); + assertThat(result.getPageable()).isNotNull(); + assertThat(result.getPageable().getPageNumber()).isEqualTo(3); + assertThat(result.getPageable().getPageSize()).isEqualTo(2); + assertThat(result.getPageable().getSort().getOrderFor("firstName").getDirection()) + .isEqualTo(Sort.Direction.ASC); + } + } diff --git a/spring-cloud-openfeign-core/src/test/resources/withPageableAliasHyphen.json b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasHyphen.json new file mode 100644 index 000000000..433c1ff0a --- /dev/null +++ b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasHyphen.json @@ -0,0 +1,77 @@ +{ + "content": [ + { + "id": 3, + "lastName": "Williams", + "firstName": "Thomas", + "email": "w.t@my.domain.com" + }, + { + "id": 1, + "lastName": "Smith", + "firstName": "James", + "email": "s.j@my.domain.com" + }, + { + "id": 11, + "lastName": "Scott", + "firstName": "Steven", + "email": "s.s@my.domain.com" + }, + { + "id": 8, + "lastName": "Rodriguez", + "firstName": "Daniel", + "email": "r.d@my.domain.com" + }, + { + "id": 9, + "lastName": "Martinez", + "firstName": "Robert", + "email": "m.r@my.domain.com" + }, + { + "id": 5, + "lastName": "Jones", + "firstName": "James", + "email": "j.j@my.domain.com" + }, + { + "id": 2, + "lastName": "Johnson", + "firstName": "Robert", + "email": "j.r@my.domain.com" + }, + { + "id": 6, + "lastName": "Garcia", + "firstName": "William", + "email": "g.w@my.domain.com" + }, + { + "id": 7, + "lastName": "Davis", + "firstName": "Richard", + "email": "d.r@my.domain.com" + }, + { + "id": 4, + "lastName": "Brown", + "firstName": "Paul", + "email": "b.p@my.domain.com" + } + ], + "pageable": { + "page-number": 2, + "page-size": 3, + "sort": { + "orders": [ + { + "direction": "ASC", + "property": "firstName" + } + ] + } + }, + "totalElements": 15 +} diff --git a/spring-cloud-openfeign-core/src/test/resources/withPageableAliasLowercase.json b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasLowercase.json new file mode 100644 index 000000000..73c9ae757 --- /dev/null +++ b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasLowercase.json @@ -0,0 +1,72 @@ +{ + "content": [ + { + "id": 3, + "lastName": "Williams", + "firstName": "Thomas", + "email": "w.t@my.domain.com" + }, + { + "id": 1, + "lastName": "Smith", + "firstName": "James", + "email": "s.j@my.domain.com" + }, + { + "id": 11, + "lastName": "Scott", + "firstName": "Steven", + "email": "s.s@my.domain.com" + }, + { + "id": 8, + "lastName": "Rodriguez", + "firstName": "Daniel", + "email": "r.d@my.domain.com" + }, + { + "id": 9, + "lastName": "Martinez", + "firstName": "Robert", + "email": "m.r@my.domain.com" + }, + { + "id": 5, + "lastName": "Jones", + "firstName": "James", + "email": "j.j@my.domain.com" + }, + { + "id": 2, + "lastName": "Johnson", + "firstName": "Robert", + "email": "j.r@my.domain.com" + }, + { + "id": 6, + "lastName": "Garcia", + "firstName": "William", + "email": "g.w@my.domain.com" + }, + { + "id": 7, + "lastName": "Davis", + "firstName": "Richard", + "email": "d.r@my.domain.com" + }, + { + "id": 4, + "lastName": "Brown", + "firstName": "Paul", + "email": "b.p@my.domain.com" + } + ], + "pageable": { + "pagenumber": 0, + "pagesize": 4, + "sort": { + "orders": [] + } + }, + "totalElements": 8 +} diff --git a/spring-cloud-openfeign-core/src/test/resources/withPageableAliasPascalCase.json b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasPascalCase.json new file mode 100644 index 000000000..e36bbb311 --- /dev/null +++ b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasPascalCase.json @@ -0,0 +1,77 @@ +{ + "content": [ + { + "id": 3, + "lastName": "Williams", + "firstName": "Thomas", + "email": "w.t@my.domain.com" + }, + { + "id": 1, + "lastName": "Smith", + "firstName": "James", + "email": "s.j@my.domain.com" + }, + { + "id": 11, + "lastName": "Scott", + "firstName": "Steven", + "email": "s.s@my.domain.com" + }, + { + "id": 8, + "lastName": "Rodriguez", + "firstName": "Daniel", + "email": "r.d@my.domain.com" + }, + { + "id": 9, + "lastName": "Martinez", + "firstName": "Robert", + "email": "m.r@my.domain.com" + }, + { + "id": 5, + "lastName": "Jones", + "firstName": "James", + "email": "j.j@my.domain.com" + }, + { + "id": 2, + "lastName": "Johnson", + "firstName": "Robert", + "email": "j.r@my.domain.com" + }, + { + "id": 6, + "lastName": "Garcia", + "firstName": "William", + "email": "g.w@my.domain.com" + }, + { + "id": 7, + "lastName": "Davis", + "firstName": "Richard", + "email": "d.r@my.domain.com" + }, + { + "id": 4, + "lastName": "Brown", + "firstName": "Paul", + "email": "b.p@my.domain.com" + } + ], + "pageable": { + "PageNumber": 3, + "PageSize": 2, + "sort": { + "orders": [ + { + "direction": "ASC", + "property": "firstName" + } + ] + } + }, + "totalElements": 20 +} diff --git a/spring-cloud-openfeign-core/src/test/resources/withPageableAliasUnderscore.json b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasUnderscore.json new file mode 100644 index 000000000..3667c9447 --- /dev/null +++ b/spring-cloud-openfeign-core/src/test/resources/withPageableAliasUnderscore.json @@ -0,0 +1,77 @@ +{ + "content": [ + { + "id": 3, + "lastName": "Williams", + "firstName": "Thomas", + "email": "w.t@my.domain.com" + }, + { + "id": 1, + "lastName": "Smith", + "firstName": "James", + "email": "s.j@my.domain.com" + }, + { + "id": 11, + "lastName": "Scott", + "firstName": "Steven", + "email": "s.s@my.domain.com" + }, + { + "id": 8, + "lastName": "Rodriguez", + "firstName": "Daniel", + "email": "r.d@my.domain.com" + }, + { + "id": 9, + "lastName": "Martinez", + "firstName": "Robert", + "email": "m.r@my.domain.com" + }, + { + "id": 5, + "lastName": "Jones", + "firstName": "James", + "email": "j.j@my.domain.com" + }, + { + "id": 2, + "lastName": "Johnson", + "firstName": "Robert", + "email": "j.r@my.domain.com" + }, + { + "id": 6, + "lastName": "Garcia", + "firstName": "William", + "email": "g.w@my.domain.com" + }, + { + "id": 7, + "lastName": "Davis", + "firstName": "Richard", + "email": "d.r@my.domain.com" + }, + { + "id": 4, + "lastName": "Brown", + "firstName": "Paul", + "email": "b.p@my.domain.com" + } + ], + "pageable": { + "page_number": 1, + "page_size": 2, + "sort": { + "orders": [ + { + "direction": "DESC", + "property": "lastName" + } + ] + } + }, + "totalElements": 10 +}