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 cb1da1cf7e..f9b5131cf8 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 @@ -40,6 +40,7 @@ import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; import com.fasterxml.jackson.databind.ser.BeanSerializerFactory; import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; @@ -47,6 +48,7 @@ import com.fasterxml.jackson.databind.ser.PropertyWriter; import com.fasterxml.jackson.databind.ser.SerializerFactory; import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -78,6 +80,7 @@ import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.env.PropertySource; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; +import org.springframework.util.unit.DataSize; /** * {@link Endpoint @Endpoint} to expose application properties from @@ -175,12 +178,12 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext builder.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); builder.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); builder.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false); - JsonMapper.builder(); builder.configure(MapperFeature.USE_STD_BEAN_NAMING, true); builder.serializationInclusion(Include.NON_NULL); applyConfigurationPropertiesFilter(builder); applySerializationModifier(builder); builder.addModule(new JavaTimeModule()); + builder.addModule(new ConfigurationPropertiesModule()); } private void applyConfigurationPropertiesFilter(JsonMapper.Builder builder) { @@ -463,6 +466,17 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext } + /** + * {@link SimpleModule} for configure the serializer. + */ + private static final class ConfigurationPropertiesModule extends SimpleModule { + + private ConfigurationPropertiesModule() { + addSerializer(DataSize.class, ToStringSerializer.instance); + } + + } + /** * {@link BeanSerializerModifier} to return only relevant configuration properties. */ 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 dc7b36559c..74ae21034a 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 @@ -47,6 +47,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mock.env.MockPropertySource; +import org.springframework.util.unit.DataSize; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; @@ -176,6 +177,18 @@ class ConfigurationPropertiesReportEndpointTests { } @Test + void descriptorWithDataSizeProperty() { + String configSize = "1MB"; + String stringifySize = DataSize.parse(configSize).toString(); + this.contextRunner.withUserConfiguration(DataSizePropertiesConfiguration.class) + .withPropertyValues(String.format("data.size=%s", configSize)).run(assertProperties("data", + (properties) -> assertThat(properties.get("size")).isEqualTo(stringifySize), (inputs) -> { + Map size = (Map) inputs.get("size"); + assertThat(size.get("value")).isEqualTo(configSize); + assertThat(size.get("origin")).isEqualTo("\"data.size\" from property source \"test\""); + })); + } + void sanitizeLists() { new ApplicationContextRunner() .withUserConfiguration(EndpointConfigWithShowNever.class, SensiblePropertiesConfiguration.class) @@ -702,6 +715,27 @@ class ConfigurationPropertiesReportEndpointTests { } + @Configuration(proxyBeanMethods = false) + @EnableConfigurationProperties(DataSizeProperties.class) + static class DataSizePropertiesConfiguration { + + } + + @ConfigurationProperties("data") + public static class DataSizeProperties { + + private DataSize size; + + public DataSize getSize() { + return this.size; + } + + public void setSize(DataSize size) { + this.size = size; + } + + } + @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(Gh4415Properties.class) static class Gh4415PropertiesConfiguration {