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 f1545096eb56..00df14059d48 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 @@ -41,6 +41,7 @@ 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; @@ -48,6 +49,7 @@ 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; @@ -80,6 +82,7 @@ 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 @@ -188,12 +191,12 @@ protected void configureJsonMapper(JsonMapper.Builder builder) { 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) { @@ -474,6 +477,17 @@ public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider } + /** + * {@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 cc424053b4b8..32cbf8ea5809 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 @@ -46,6 +46,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; 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; @@ -168,6 +169,19 @@ void descriptorWithMixedBooleanProperty() { (properties) -> assertThat(properties.get("mixedBoolean")).isEqualTo(true))); } + @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\""); + })); + } + @Test void sanitizeWithDefaultSettings() { this.contextRunner.withUserConfiguration(TestPropertiesConfiguration.class) @@ -690,6 +704,27 @@ public void setMixedBoolean(Boolean mixedBoolean) { } + @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 {