From 6f67896eba51751ae92058eccb1cf0dc77bcf79a Mon Sep 17 00:00:00 2001 From: Jonas Konrad Date: Fri, 18 Nov 2022 15:55:05 +0100 Subject: [PATCH] implement JsonFormat for creator properties (#8365) Fixes #8330 --- .../modules/BeanIntrospectionModule.java | 32 +++++++++++++++++-- .../BeanIntrospectionModuleRecordSpec.groovy | 30 +++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/jackson-databind/src/main/java/io/micronaut/jackson/modules/BeanIntrospectionModule.java b/jackson-databind/src/main/java/io/micronaut/jackson/modules/BeanIntrospectionModule.java index 936bf048fd3..f374f801583 100644 --- a/jackson-databind/src/main/java/io/micronaut/jackson/modules/BeanIntrospectionModule.java +++ b/jackson-databind/src/main/java/io/micronaut/jackson/modules/BeanIntrospectionModule.java @@ -27,7 +27,19 @@ import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.SerializableString; import com.fasterxml.jackson.core.io.SerializedString; -import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.DeserializationConfig; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyMetadata; +import com.fasterxml.jackson.databind.PropertyName; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -291,7 +303,7 @@ public JsonSerializer build() { } } }; - + newBuilder.setAnyGetter(builder.getAnyGetter()); final List properties = builder.getProperties(); final Collection> beanProperties = introspection.getBeanProperties(); @@ -534,6 +546,22 @@ public Object setAndReturn(Object instance, Object value) throws IOException { } return null; } + + @Override + public JsonFormat.Value findPropertyFormat(MapperConfig config, Class baseType) { + JsonFormat.Value v1 = config.getDefaultPropertyFormat(baseType); + JsonFormat.Value v2 = null; + if (property != null) { + AnnotationValue formatAnnotation = property.getAnnotation(JsonFormat.class); + if (formatAnnotation != null) { + v2 = parseJsonFormat(formatAnnotation); + } + } + if (v1 == null) { + return (v2 == null) ? EMPTY_FORMAT : v2; + } + return (v2 == null) ? v1 : v1.withOverrides(v2); + } }; } } diff --git a/jackson-databind/src/test/groovy/io/micronaut/jackson/modules/BeanIntrospectionModuleRecordSpec.groovy b/jackson-databind/src/test/groovy/io/micronaut/jackson/modules/BeanIntrospectionModuleRecordSpec.groovy index 73d21158c0e..83fc3eaa690 100644 --- a/jackson-databind/src/test/groovy/io/micronaut/jackson/modules/BeanIntrospectionModuleRecordSpec.groovy +++ b/jackson-databind/src/test/groovy/io/micronaut/jackson/modules/BeanIntrospectionModuleRecordSpec.groovy @@ -8,6 +8,9 @@ import io.micronaut.context.annotation.Requires import io.micronaut.core.beans.BeanIntrospection import jakarta.inject.Singleton import spock.lang.IgnoreIf +import spock.lang.Issue + +import java.time.LocalDateTime @IgnoreIf({ !jvm.isJava14Compatible() }) class BeanIntrospectionModuleRecordSpec extends AbstractTypeElementSpec { @@ -36,6 +39,33 @@ record Test(String foo, String bar) { ignoreReflectiveProperties << [true, false] } + @Issue('https://github.com/micronaut-projects/micronaut-core/issues/8330') + def 'JsonFormat'() { + given: + BeanIntrospection introspection = buildBeanIntrospection('test.Test', ''' +package test; +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.micronaut.core.annotation.Introspected; + +@Introspected +record Test(@JsonFormat(pattern = "dd.MM.yyyy HH:mm:ss") LocalDateTime date) { +} +''') + def ctx = ApplicationContext.run(['spec.name': 'BeanIntrospectionModuleRecordSpec']) + ctx.getBean(StaticBeanIntrospectionModule).introspectionMap[introspection.beanType] = introspection + ctx.getBean(BeanIntrospectionModule).ignoreReflectiveProperties = ignoreReflectiveProperties + def mapper = ctx.getBean(ObjectMapper) + + when: + def value = mapper.readValue('{"date":"13.11.2022 22:44:55"}', introspection.beanType) + then: + value.date == LocalDateTime.of(2022, 11, 13, 22, 44, 55) + + where: + ignoreReflectiveProperties << [true, false] + } + @Singleton @Replaces(BeanIntrospectionModule) @Requires(property = "spec.name", value = 'BeanIntrospectionModuleRecordSpec')