Skip to content

Commit 98b99a5

Browse files
authored
GH-4205: Allow JSON (de)serialize null values in Kotlin
Fixes: #4205 - Replaced `byte[]` with `byte @nullable []` for `JacksonJson(De)serializer` to be able to return and receive null values Signed-off-by: Trond Ziarkowski <trondgzi@gmail.com>
1 parent 28b92a7 commit 98b99a5

File tree

4 files changed

+103
-6
lines changed

4 files changed

+103
-6
lines changed

spring-kafka/src/main/java/org/springframework/kafka/support/serializer/JacksonJsonDeserializer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
* @author Ivan Ponomarev
6666
* @author Omer Celik
6767
* @author Soby Chacko
68+
* @author Trond Ziarkowski
6869
*
6970
* @since 4.0
7071
*/
@@ -566,7 +567,7 @@ private void doAddTrustedPackages(String... packages) {
566567
}
567568

568569
@Override
569-
public @Nullable T deserialize(String topic, Headers headers, byte[] data) {
570+
public @Nullable T deserialize(String topic, Headers headers, byte @Nullable [] data) {
570571
if (data == null) {
571572
return null;
572573
}
@@ -597,7 +598,7 @@ private void doAddTrustedPackages(String... packages) {
597598
}
598599

599600
@Override
600-
public @Nullable T deserialize(String topic, byte[] data) {
601+
public @Nullable T deserialize(String topic, byte @Nullable [] data) {
601602
if (data == null) {
602603
return null;
603604
}

spring-kafka/src/main/java/org/springframework/kafka/support/serializer/JacksonJsonSerializer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
* @author Wang Zhiyang
5555
* @author Omer Celik
5656
* @author Soby Chacko
57+
* @author Trond Ziarkowski
5758
*
5859
* @since 4.0
5960
*/
@@ -202,9 +203,8 @@ protected static Map<String, Class<?>> createMappings(String mappings) {
202203
return mappingsMap;
203204
}
204205

205-
@SuppressWarnings("NullAway") // Dataflow analysis limitation
206206
@Override
207-
public byte[] serialize(String topic, Headers headers, @Nullable T data) {
207+
public byte @Nullable [] serialize(String topic, Headers headers, @Nullable T data) {
208208
if (data == null) {
209209
return null;
210210
}
@@ -214,9 +214,8 @@ public byte[] serialize(String topic, Headers headers, @Nullable T data) {
214214
return serialize(topic, data);
215215
}
216216

217-
@SuppressWarnings("NullAway") // Dataflow analysis limitation
218217
@Override
219-
public byte[] serialize(String topic, @Nullable T data) {
218+
public byte @Nullable [] serialize(String topic, @Nullable T data) {
220219
if (data == null) {
221220
return null;
222221
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2016-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.kafka.support.serializer
18+
19+
import org.assertj.core.api.Assertions.assertThat
20+
import org.junit.jupiter.api.Test
21+
import tools.jackson.core.type.TypeReference
22+
import kotlin.text.Charsets.UTF_8
23+
24+
/**
25+
* @author Trond Ziarkowski
26+
*
27+
* @since 4.0.1
28+
*/
29+
class JacksonJsonDeserializerTests {
30+
private val targetType = object : TypeReference<DeserializedData>() {}
31+
private val deserializer = JacksonJsonDeserializer(targetType).ignoreTypeHeaders()
32+
33+
@Test
34+
fun `Expect deserializing a non-null value to work`() {
35+
val dataToDeserialize = """{"value":"test-data"}""".toByteArray(UTF_8)
36+
val deserializedData = deserializer.deserialize("topic", dataToDeserialize)
37+
38+
assertThat(deserializedData).isEqualTo(DeserializedData("test-data"))
39+
}
40+
41+
@Test
42+
fun `Expect deserializing a null value to work`() {
43+
val deserializedData = deserializer.deserialize("topic", null)
44+
assertThat(deserializedData).isNull()
45+
}
46+
47+
private data class DeserializedData(val value: String)
48+
49+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2016-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.kafka.support.serializer
18+
19+
import org.assertj.core.api.Assertions.assertThat
20+
import org.junit.jupiter.api.Test
21+
import tools.jackson.core.type.TypeReference
22+
import kotlin.text.Charsets.UTF_8
23+
24+
/**
25+
* @author Trond Ziarkowski
26+
*
27+
* @since 4.0.1
28+
*/
29+
class JacksonJsonSerializerTests {
30+
private val targetType = object : TypeReference<DataToSerialize>() {}
31+
private val serializer = JacksonJsonSerializer(targetType).noTypeInfo()
32+
33+
@Test
34+
fun `Expect serializing a non-null value to work`() {
35+
val dataToSerialize = DataToSerialize("test-data")
36+
val bytes = serializer.serialize("topic", dataToSerialize)
37+
38+
assertThat(bytes?.toString(UTF_8)).isEqualTo("""{"value":"test-data"}""")
39+
}
40+
41+
@Test
42+
fun `Expect serializing a null value to work`() {
43+
val bytes = serializer.serialize("topic", null)
44+
assertThat(bytes).isNull()
45+
}
46+
47+
private data class DataToSerialize(val value: String)
48+
}

0 commit comments

Comments
 (0)