diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java index ee9a1932b153..221d7c757194 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java @@ -394,7 +394,7 @@ private Map getInput(ConfigurationProperty candidate, Object san } private Object stringifyIfNecessary(Object value) { - if (value == null || value.getClass().isPrimitive()) { + if (value == null || ClassUtils.isPrimitiveOrWrapper(value.getClass()) || value instanceof String) { return value; } if (CharSequence.class.isAssignableFrom(value.getClass())) { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java index c6cfc7b1de35..816c4d1c8870 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java @@ -44,7 +44,10 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockPropertySource; import org.springframework.util.unit.DataSize; @@ -143,6 +146,21 @@ void descriptorWithDurationProperty() { .isEqualTo(Duration.ofSeconds(10).toString()))); } + @Test // gh-36076 + void descriptorWithWrapperProperty() { + this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class).withInitializer((context) -> { + ConfigurableEnvironment environment = context.getEnvironment(); + Map map = Collections.singletonMap("test.wrapper", 10); + PropertySource propertySource = new MapPropertySource("test", map); + environment.getPropertySources().addLast(propertySource); + }) + .run(assertProperties("test", (properties) -> assertThat(properties.get("wrapper")).isEqualTo(10), + (inputs) -> { + Map wrapper = (Map) inputs.get("wrapper"); + assertThat(wrapper.get("value")).isEqualTo(10); + })); + } + @Test void descriptorWithNonCamelCaseProperty() { this.contextRunner.withUserConfiguration(MixedCasePropertiesConfiguration.class) @@ -476,6 +494,8 @@ public static class TestProperties { private String ignored = "dummy"; + private Integer wrapper; + public String getDbPassword() { return this.dbPassword; } @@ -512,6 +532,14 @@ public String getIgnored() { return this.ignored; } + public Integer getWrapper() { + return this.wrapper; + } + + public void setWrapper(Integer wrapper) { + this.wrapper = wrapper; + } + } @Configuration(proxyBeanMethods = false)