From be06eac43c4985e685597009d5773cab90fc7026 Mon Sep 17 00:00:00 2001 From: johnflynn Date: Fri, 10 Apr 2020 11:32:26 -0400 Subject: [PATCH 1/4] Added addSerializer and addDeserializer extensions to SimpleModule for accepting KClass and registering both the java class, and javaObjectType for the KClass. --- .../jackson/module/kotlin/Extensions.kt | 16 ++++- .../test/KClassSerializerDeserializerTest.kt | 65 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt index 079b0e607..5e1b11bb1 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt @@ -7,10 +7,14 @@ import com.fasterxml.jackson.databind.JsonMappingException import com.fasterxml.jackson.databind.MappingIterator import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectReader +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonSerializer import java.io.File import java.io.InputStream import java.io.Reader import java.net.URL +import kotlin.reflect.KClass fun jacksonObjectMapper(): ObjectMapper = ObjectMapper().registerKotlinModule() fun ObjectMapper.registerKotlinModule(): ObjectMapper = this.registerModule(KotlinModule()) @@ -35,4 +39,14 @@ inline fun ObjectReader.readValuesTyped(jp: JsonParser): Iterator inline fun ObjectReader.treeToValue(n: TreeNode): T? = treeToValue(n, T::class.java) internal fun JsonMappingException.wrapWithPath(refFrom: Any?, refFieldName: String) = JsonMappingException.wrapWithPath(this, refFrom, refFieldName) -internal fun JsonMappingException.wrapWithPath(refFrom: Any?, index: Int) = JsonMappingException.wrapWithPath(this, refFrom, index) \ No newline at end of file +internal fun JsonMappingException.wrapWithPath(refFrom: Any?, index: Int) = JsonMappingException.wrapWithPath(this, refFrom, index) + +inline fun SimpleModule.addSerializer(kClass: KClass, serializer: JsonSerializer) = this.apply { + addSerializer(kClass.java, serializer) + addSerializer(kClass.javaObjectType, serializer) +} + +inline fun SimpleModule.addDeserializer(kClass: KClass, deserializer: JsonDeserializer) = this.apply { + addDeserializer(kClass.java, deserializer) + addDeserializer(kClass.javaObjectType, deserializer) +} \ No newline at end of file diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt new file mode 100644 index 000000000..c154c4532 --- /dev/null +++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt @@ -0,0 +1,65 @@ +package com.fasterxml.jackson.module.kotlin.test + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.* +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.module.kotlin.addDeserializer +import com.fasterxml.jackson.module.kotlin.addSerializer +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.Test +import java.math.BigDecimal +import java.math.RoundingMode + +class KClassSerializerDeserializerTest { + + val objectMapper = jacksonObjectMapper() + .registerModule(SimpleModule() + .addSerializer(Double::class, RoundingSerializer()) + .addDeserializer(Double::class, RoundingDeserializer())) + + + @Test + fun `test custom serializer expecting object serialized with rounding serializer applied`() { + val jsonString = objectMapper.writeValueAsString(TestDoubleData(nonNullVal = 1.5567, nullVal = 1.5567)) + val testResult = objectMapper.readValue(jsonString, TestDoubleData::class.java) + assertThat(testResult.nonNullVal, equalTo(1.56)) + assertThat(testResult.nullVal, equalTo(1.56)) + } + + @Test + fun `test custom deserializer expecting object deserialized with rounding deserializer applied`() { + val testResult = objectMapper.readValue(""" + { + "nonNullVal":1.5567, + "nullVal":1.5567 + } + """.trimIndent()) + assertThat(testResult.nonNullVal, equalTo(1.56)) + assertThat(testResult.nullVal, equalTo(1.56)) + } +} + +data class TestDoubleData( + val nonNullVal: Double, + val nullVal: Double? +) + +class RoundingSerializer : JsonSerializer() { + override fun serialize(value: Double?, gen: JsonGenerator?, serializers: SerializerProvider?) { + value?.let { + gen?.writeNumber(BigDecimal(it).setScale(2, RoundingMode.HALF_UP)) + } + } +} + +class RoundingDeserializer : JsonDeserializer() { + override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Double? { + return BigDecimal(p?.valueAsString) + .setScale(2, RoundingMode.HALF_UP) + .toDouble() + } +} \ No newline at end of file From cebd2068c77dea482dd3628ffd19bb7b9491b7ea Mon Sep 17 00:00:00 2001 From: Drew Stephens Date: Sun, 26 Apr 2020 15:34:32 -0400 Subject: [PATCH 2/4] Make test values distinguishable --- .../kotlin/test/KClassSerializerDeserializerTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt index c154c4532..649b8aa63 100644 --- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt +++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/KClassSerializerDeserializerTest.kt @@ -24,10 +24,10 @@ class KClassSerializerDeserializerTest { @Test fun `test custom serializer expecting object serialized with rounding serializer applied`() { - val jsonString = objectMapper.writeValueAsString(TestDoubleData(nonNullVal = 1.5567, nullVal = 1.5567)) + val jsonString = objectMapper.writeValueAsString(TestDoubleData(nonNullVal = 1.5567, nullVal = 1.5678)) val testResult = objectMapper.readValue(jsonString, TestDoubleData::class.java) assertThat(testResult.nonNullVal, equalTo(1.56)) - assertThat(testResult.nullVal, equalTo(1.56)) + assertThat(testResult.nullVal, equalTo(1.57)) } @Test @@ -35,11 +35,11 @@ class KClassSerializerDeserializerTest { val testResult = objectMapper.readValue(""" { "nonNullVal":1.5567, - "nullVal":1.5567 + "nullVal":1.5678 } """.trimIndent()) assertThat(testResult.nonNullVal, equalTo(1.56)) - assertThat(testResult.nullVal, equalTo(1.56)) + assertThat(testResult.nullVal, equalTo(1.57)) } } From 95c1021668d199d488eaed613a7619fcf9424576 Mon Sep 17 00:00:00 2001 From: Drew Stephens Date: Sun, 26 Apr 2020 16:06:07 -0400 Subject: [PATCH 3/4] Stub out 2.12.0 --- release-notes/VERSION-2.x | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 964e1bee3..51f458422 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -4,6 +4,10 @@ Project: jackson-module-kotlin === Releases === ------------------------------------------------------------------------ +2.12.0 (not yet released) + +- + 2.11.1 (not yet released) - From 5c5e3b0e6dcf714eaeb4fc597f0405f9d133f580 Mon Sep 17 00:00:00 2001 From: johnflynn Date: Sun, 26 Apr 2020 16:36:14 -0400 Subject: [PATCH 4/4] Updated credits and release notes for PR #322. --- release-notes/CREDITS-2.x | 4 ++++ release-notes/VERSION-2.x | 2 ++ 2 files changed, 6 insertions(+) diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index b8c606c07..3337ab9ea 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -50,3 +50,7 @@ Drew Stephens (dinomite@github) Mateusz Stefek (MateuszStefek@github) * Reported #321: Make MissingKotlinParameterException a descendant of MismatchedInputException + +John Flynn (Neuman968@github) +* Contributed extension methods for SimpleModule to add serializer and deserializer extension functions for KClass #322 + (2.12.x) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 51f458422..131936b78 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -6,6 +6,8 @@ Project: jackson-module-kotlin 2.12.0 (not yet released) +#322 Added extension methods to SimpleModule addSerializer and addDeserializer to support KClass arguments that + register the serializer/deserializer for both the java type and java class. - 2.11.1 (not yet released)