Skip to content

Commit 7beaa60

Browse files
garyrussellartembilan
authored andcommitted
GH-794: Json Deserializer - remove type headers
Resolves #794
1 parent 9f828a8 commit 7beaa60

File tree

6 files changed

+54
-0
lines changed

6 files changed

+54
-0
lines changed

spring-kafka/src/main/java/org/springframework/kafka/support/converter/DefaultJackson2JavaTypeMapper.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,19 @@ public Class<?> toClass(Headers headers) {
182182
return toJavaType(headers).getRawClass();
183183
}
184184

185+
@Override
186+
public void removeHeaders(Headers headers) {
187+
try {
188+
headers.remove(getClassIdFieldName());
189+
headers.remove(getContentClassIdFieldName());
190+
headers.remove(getKeyClassIdFieldName());
191+
headers.remove(KEY_DEFAULT_CLASSID_FIELD_NAME);
192+
headers.remove(KEY_DEFAULT_CONTENT_CLASSID_FIELD_NAME);
193+
headers.remove(KEY_DEFAULT_KEY_CLASSID_FIELD_NAME);
194+
}
195+
catch (Exception e) {
196+
// NOSONAR
197+
}
198+
}
199+
185200
}

spring-kafka/src/main/java/org/springframework/kafka/support/converter/Jackson2JavaTypeMapper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,13 @@ default void setTypePrecedence(TypePrecedence typePrecedence) {
6868

6969
void addTrustedPackages(String... packages);
7070

71+
/**
72+
* Remove the type information headers.
73+
* @param headers the headers.
74+
* @since 2.2
75+
*/
76+
default void removeHeaders(Headers headers) {
77+
// NOSONAR
78+
}
79+
7180
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ public class JsonDeserializer<T> implements ExtendedDeserializer<T> {
8989
*/
9090
public static final String TYPE_MAPPINGS = JsonSerializer.TYPE_MAPPINGS;
9191

92+
/**
93+
* Kafka config property for removing type headers.
94+
*/
95+
public static final String REMOVE_TYPE_INFO_HEADERS = "spring.json.remove.type.headers";
96+
9297
protected final ObjectMapper objectMapper;
9398

9499
protected Class<T> targetType;
@@ -99,6 +104,8 @@ public class JsonDeserializer<T> implements ExtendedDeserializer<T> {
99104

100105
private boolean typeMapperExplicitlySet = false;
101106

107+
private boolean removeTypeHeaders = true;
108+
102109
/**
103110
* Construct an instance with a default {@link ObjectMapper}.
104111
*/
@@ -203,6 +210,16 @@ public void setUseTypeMapperForKey(boolean isKey) {
203210
}
204211
}
205212

213+
/**
214+
* Set to false to retain type information headers after deserialization.
215+
* Default true.
216+
* @param removeTypeHeaders true to remove headers.
217+
* @since 2.1
218+
*/
219+
public void setRemoveTypeHeaders(boolean removeTypeHeaders) {
220+
this.removeTypeHeaders = removeTypeHeaders;
221+
}
222+
206223
@SuppressWarnings("unchecked")
207224
@Override
208225
public void configure(Map<String, ?> configs, boolean isKey) {
@@ -263,6 +280,9 @@ else if (configs.get(VALUE_DEFAULT_TYPE) instanceof String) {
263280
((AbstractJavaTypeMapper) this.typeMapper).setIdClassMapping(
264281
JsonSerializer.createMappings((String) configs.get(JsonSerializer.TYPE_MAPPINGS)));
265282
}
283+
if (configs.containsKey(REMOVE_TYPE_INFO_HEADERS)) {
284+
this.removeTypeHeaders = Boolean.parseBoolean((String) configs.get(REMOVE_TYPE_INFO_HEADERS));
285+
}
266286
}
267287

268288
/**
@@ -292,6 +312,9 @@ public T deserialize(String topic, Headers headers, byte[] data) {
292312
reader = this.objectMapper.readerFor(javaType);
293313
}
294314
}
315+
if (this.removeTypeHeaders) {
316+
this.typeMapper.removeHeaders(headers);
317+
}
295318
if (reader == null) {
296319
reader = this.reader;
297320
}

spring-kafka/src/test/java/org/springframework/kafka/listener/KafkaMessageListenerContainerTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,7 @@ public void testJsonSerDeHeaderSimpleType() throws Exception {
16471647
assertThat(received.get().value()).isInstanceOf(Foo.class);
16481648
container.stop();
16491649
this.logger.info("Stop JSON2");
1650+
assertThat(received.get().headers().iterator().hasNext()).isFalse();
16501651
}
16511652

16521653
@Test

src/reference/asciidoc/kafka.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,11 +1629,15 @@ In addition, the serializer/deserializer can be configured using Kafka propertie
16291629

16301630
- `JsonSerializer.ADD_TYPE_INFO_HEADERS` (default `true`); set to `false` to disable this feature on the `JsonSerializer` (sets the `addTypeInfo` property).
16311631
- `JsonSerializer.TYPE_MAPPINGS` (default `empty`); see below.
1632+
- `JsonDeserializer.REMOVE_TYPE_INFO_HEADERS` (default `true`); set to `false` to retain headers set by the serializer.
16321633
- `JsonDeserializer.KEY_DEFAULT_TYPE`; fallback type for deserialization of keys if no header information is present.
16331634
- `JsonDeserializer.VALUE_DEFAULT_TYPE`; fallback type for deserialization of values if no header information is present.
16341635
- `JsonDeserializer.TRUSTED_PACKAGES` (default `java.util`, `java.lang`); comma-delimited list of package patterns allowed for deserialization; `*` means deserialize all.
16351636
- `JsonDeserializer.TYPE_MAPPINGS` (default `empty`); see below.
16361637

1638+
Starting with version 2.2, the type information headers (if added by the serializer) will be removed by the deserializer.
1639+
You can revert to the previous behavior by setting the `removeTypeHeaders` property to false, either directly on the deserializer, or with the configuration property described above.
1640+
16371641
**Mapping Types**
16381642

16391643
Starting with version 2.2, you can now provide type mappings using the properties in the above list; previously you had to customize the type mapper within the serializer, deserializer.

src/reference/asciidoc/whats-new.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ You can now provide type mapping information using producer/consumer properties.
7070

7171
New constructors are available on the deserializer to allow overriding the type header information with the supplied target type.
7272

73+
The JsonDeserializer will now remove any type information headers by default.
74+
7375
See <<serdes>> for more information.
7476

7577
==== Kafka Streams Changes

0 commit comments

Comments
 (0)