From 0c4c19bfcd891b42fa59c4817280b0e979976585 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Wed, 27 Jan 2021 20:10:42 -0500 Subject: [PATCH 1/2] Better classpath protections for pageable modules. Fixes gh-474 # Conflicts: # spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java --- .../openfeign/FeignAutoConfiguration.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java index a68f3d81..a27c66d9 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java @@ -60,6 +60,8 @@ import org.springframework.cloud.openfeign.support.SortJacksonModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Sort; /** * @author Spencer Gibb @@ -91,22 +93,24 @@ public class FeignAutoConfiguration { return context; } - @Bean - @ConditionalOnMissingBean(PageJacksonModule.class) - @ConditionalOnClass(name = "org.springframework.data.domain.Page") + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ Module.class, Page.class, Sort.class }) @ConditionalOnProperty(value = "feign.autoconfiguration.jackson.enabled", havingValue = "true") - public Module pageJacksonModule() { - return new PageJacksonModule(); - } + protected static class FeignJacksonConfiguration { + + @Bean + @ConditionalOnMissingBean(PageJacksonModule.class) + public PageJacksonModule pageJacksonModule() { + return new PageJacksonModule(); + } + + @Bean + @ConditionalOnMissingBean(SortJacksonModule.class) + public SortJacksonModule sortModule() { + return new SortJacksonModule(); + } - @Bean - @ConditionalOnMissingBean(SortJacksonModule.class) - @ConditionalOnClass(name = "org.springframework.data.domain.Sort") - @ConditionalOnProperty(value = "feign.autoconfiguration.jackson.enabled", - havingValue = "true") - public Module sortModule() { - return new SortJacksonModule(); } @Configuration(proxyBeanMethods = false) From 27a396797516799857bfee66da3d644b6c1bbac6 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 2 Feb 2021 14:10:46 +0100 Subject: [PATCH 2/2] Support all non-deprecated Jackson naming strategies for page deserialization. Fixes gh-170. (#477) --- .../cloud/openfeign/support/PageJacksonModule.java | 6 +++++- .../openfeign/support/PageJacksonModuleTests.java | 13 +++++++++---- 2 files changed, 14 insertions(+), 5 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 72662101..b1201832 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 @@ -20,6 +20,7 @@ import java.util.Iterator; import java.util.List; import java.util.function.Function; +import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.Version; @@ -36,6 +37,7 @@ import org.springframework.data.domain.Sort; * This Jackson module provides support to deserialize Spring {@link Page} objects. * * @author Pascal Büttiker + * @author Olga Maciaszek-Sharma */ public class PageJacksonModule extends Module { @@ -65,7 +67,9 @@ public class PageJacksonModule extends Module { SimplePageImpl(@JsonProperty("content") List content, @JsonProperty("number") int number, @JsonProperty("size") int size, - @JsonProperty("totalElements") long totalElements, + @JsonProperty("totalElements") @JsonAlias({ "total-elements", + "total_elements", "totalelements", + "TotalElements" }) long totalElements, @JsonProperty("sort") Sort sort) { PageRequest pageRequest; if (sort != null) { 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 465617fd..8cf97fe2 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 @@ -19,14 +19,18 @@ package org.springframework.cloud.openfeign.support; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.data.domain.Page; import static org.assertj.core.api.Assertions.assertThat; /** + * Test for {@link PageJacksonModule}. + * * @author Ruben Vervaeke + * @author Olga Maciaszek-Sharma */ public class PageJacksonModuleTests { @@ -38,10 +42,11 @@ public class PageJacksonModuleTests { objectMapper.registerModule(new PageJacksonModule()); } - @Test - public void deserializePage() throws JsonProcessingException { + @ParameterizedTest + @ValueSource(strings = {"totalElements", "total-elements", "total_elements", "totalelements", "TotalElements"}) + public void deserializePage(String totalElements) throws JsonProcessingException { // Given - String pageJson = "{\"content\":[\"A name\"], \"number\":1, \"size\":2, \"totalElements\": 3}"; + String pageJson = "{\"content\":[\"A name\"], \"number\":1, \"size\":2, \"" + totalElements + "\": 3}"; // When Page result = objectMapper.readValue(pageJson, Page.class); // Then