You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GH-3930: Add Jackson 3 support; deprecate Jackson 2
Fixes: #3930
* Manage dependencies, similar way we do for Jackson 2
* Add Jackson 3 counterparts for existing Jackson 2 based classes (mostly copy/paste)
* Deprectate Jackson 2 classes
* Update tests
* Initial round of updates in docs
Signed-off-by: Soby Chacko <[email protected]>
Copy file name to clipboardExpand all lines: samples/sample-01/README.adoc
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
This sample demonstrates a simple producer and consumer; the producer sends objects of type `Foo1` and the consumer receives objects of type `Foo2` (the objects have the same field, `foo`).
4
4
5
-
The producer uses a `JsonSerializer`; the consumer uses the `ByteArrayDeserializer`, together with a `JsonMessageConverter` which converts to the type of the listener method argument.
5
+
The producer uses a `JacksonJsonSerializer`; the consumer uses the `ByteArrayDeserializer`, together with a `JacksonJsonMessageConverter` which converts to the type of the listener method argument.
6
6
7
7
Run the application and use curl to send some data:
Copy file name to clipboardExpand all lines: samples/sample-02/README.adoc
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
This sample demonstrates a simple producer and a multi-method consumer; the producer sends objects of types `Foo1` and `Bar1` and the consumer receives objects of type `Foo2` and `Bar2` (the objects have the same field, `foo`).
4
4
5
-
The producer uses a `JsonSerializer`; the consumer uses a `ByteArrayDeserializer`, together with a `ByteArrayJsonMessageConverter` which converts to the required type of the listener method argument.
5
+
The producer uses a `JacksonJsonSerializer`; the consumer uses a `ByteArrayJacksonDeserializer`, together with a `ByteArrayJacksonJsonMessageConverter` which converts to the required type of the listener method argument.
6
6
We can't infer the type in this case (because the type is used to choose the method to call).
7
7
We therefore configure type mapping on the producer and consumer side.
8
8
See the `application.yml` for the producer side and the `converter` bean on the consumer side.
Copy file name to clipboardExpand all lines: spring-kafka-docs/src/main/antora/modules/ROOT/pages/kafka/receiving-messages/class-level-kafkalistener.adoc
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,7 +35,7 @@ static class MultiListenerBean {
35
35
Starting with version 2.1.3, you can designate a `@KafkaHandler` method as the default method that is invoked if there is no match on other methods.
36
36
At most, one method can be so designated.
37
37
When using `@KafkaHandler` methods, the payload must have already been converted to the domain object (so the match can be performed).
38
-
Use a custom deserializer, the `JsonDeserializer`, or the `JsonMessageConverter` with its `TypePrecedence` set to `TYPE_ID`.
38
+
Use a custom deserializer, the `JacksonJsonDeserializer`, or the `JacksonJsonMessageConverter` with its `TypePrecedence` set to `TYPE_ID`.
39
39
See xref:kafka/serdes.adoc[Serialization, Deserialization, and Message Conversion] for more information.
40
40
41
41
IMPORTANT: Due to some limitations in the way Spring resolves method arguments, a default `@KafkaHandler` cannot receive discrete headers; it must use the `ConsumerRecordMetadata` as discussed in xref:kafka/receiving-messages/listener-annotation.adoc#consumer-record-metadata[Consumer Record Metadata].
Copy file name to clipboardExpand all lines: spring-kafka-docs/src/main/antora/modules/ROOT/pages/kafka/serdes.adoc
+26-26Lines changed: 26 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -75,18 +75,18 @@ A `ToFromStringSerde` is also provided, for use with Kafka Streams.
75
75
[[json-serde]]
76
76
== JSON
77
77
78
-
Spring for Apache Kafka also provides `JsonSerializer` and `JsonDeserializer` implementations that are based on the
78
+
Spring for Apache Kafka also provides `JacksonJsonSerializer` and `JacksonJsonDeserializer` implementations that are based on the
79
79
Jackson JSON object mapper.
80
-
The `JsonSerializer` allows writing any Java object as a JSON `byte[]`.
81
-
The `JsonDeserializer` requires an additional `Class<?> targetType` argument to allow the deserialization of a consumed `byte[]` to the proper target object.
82
-
The following example shows how to create a `JsonDeserializer`:
80
+
The `JacksonJsonSerializer` allows writing any Java object as a JSON `byte[]`.
81
+
The `JacksonJsonDeserializer` requires an additional `Class<?> targetType` argument to allow the deserialization of a consumed `byte[]` to the proper target object.
82
+
The following example shows how to create a `JacksonJsonDeserializer`:
83
83
84
84
[source, java]
85
85
----
86
-
JsonDeserializer<Thing> thingDeserializer = new JsonDeserializer<>(Thing.class);
86
+
JacksonJsonDeserializer<Thing> thingDeserializer = new JacksonJsonDeserializer<>(Thing.class);
87
87
----
88
88
89
-
You can customize both `JsonSerializer` and `JsonDeserializer` with an `ObjectMapper`.
89
+
You can customize both `JacksonJsonSerializer` and `JacksonJsonDeserializer` with an `ObjectMapper`.
90
90
You can also extend them to implement some particular configuration logic in the `configure(Map<String, ?> configs, boolean isKey)` method.
91
91
92
92
Starting with version 2.3, all the JSON-aware components are configured by default with a `JacksonUtils.enhancedObjectMapper()` instance, which comes with the `MapperFeature.DEFAULT_VIEW_INCLUSION` and `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` features disabled.
@@ -104,22 +104,22 @@ They have no effect if you have provided `Serializer` and `Deserializer` instanc
104
104
[[serdes-json-config]]
105
105
=== Configuration Properties
106
106
107
-
* `JsonSerializer.ADD_TYPE_INFO_HEADERS` (default `true`): You can set it to `false` to disable this feature on the `JsonSerializer` (sets the `addTypeInfo` property).
108
-
* `JsonSerializer.TYPE_MAPPINGS` (default `empty`): See xref:kafka/serdes.adoc#serdes-mapping-types[Mapping Types].
109
-
* `JsonDeserializer.USE_TYPE_INFO_HEADERS` (default `true`): You can set it to `false` to ignore headers set by the serializer.
110
-
* `JsonDeserializer.REMOVE_TYPE_INFO_HEADERS` (default `true`): You can set it to `false` to retain headers set by the serializer.
111
-
* `JsonDeserializer.KEY_DEFAULT_TYPE`: Fallback type for deserialization of keys if no header information is present.
112
-
* `JsonDeserializer.VALUE_DEFAULT_TYPE`: Fallback type for deserialization of values if no header information is present.
113
-
* `JsonDeserializer.TRUSTED_PACKAGES` (default `java.util`, `java.lang`): Comma-delimited list of package patterns allowed for deserialization.
107
+
* `JacksonJsonSerializer.ADD_TYPE_INFO_HEADERS` (default `true`): You can set it to `false` to disable this feature on the `JacksonJsonSerializer` (sets the `addTypeInfo` property).
108
+
* `JacksonJsonSerializer.TYPE_MAPPINGS` (default `empty`): See xref:kafka/serdes.adoc#serdes-mapping-types[Mapping Types].
109
+
* `JacksonJsonDeserializer.USE_TYPE_INFO_HEADERS` (default `true`): You can set it to `false` to ignore headers set by the serializer.
110
+
* `JacksonJsonDeserializer.REMOVE_TYPE_INFO_HEADERS` (default `true`): You can set it to `false` to retain headers set by the serializer.
111
+
* `JacksonJsonDeserializer.KEY_DEFAULT_TYPE`: Fallback type for deserialization of keys if no header information is present.
112
+
* `JacksonJsonDeserializer.VALUE_DEFAULT_TYPE`: Fallback type for deserialization of values if no header information is present.
113
+
* `JacksonJsonDeserializer.TRUSTED_PACKAGES` (default `java.util`, `java.lang`): Comma-delimited list of package patterns allowed for deserialization.
114
114
`*` means deserializing all.
115
-
* `JsonDeserializer.TYPE_MAPPINGS` (default `empty`): See xref:kafka/serdes.adoc#serdes-mapping-types[Mapping Types].
116
-
* `JsonDeserializer.KEY_TYPE_METHOD` (default `empty`): See xref:kafka/serdes.adoc#serdes-type-methods[Using Methods to Determine Types].
117
-
* `JsonDeserializer.VALUE_TYPE_METHOD` (default `empty`): See xref:kafka/serdes.adoc#serdes-type-methods[Using Methods to Determine Types].
115
+
* `JacksonJsonDeserializer.TYPE_MAPPINGS` (default `empty`): See xref:kafka/serdes.adoc#serdes-mapping-types[Mapping Types].
116
+
* `JacksonJsonDeserializer.KEY_TYPE_METHOD` (default `empty`): See xref:kafka/serdes.adoc#serdes-type-methods[Using Methods to Determine Types].
117
+
* `JacksonJsonDeserializer.VALUE_TYPE_METHOD` (default `empty`): See xref:kafka/serdes.adoc#serdes-type-methods[Using Methods to Determine Types].
118
118
119
119
Starting with version 2.2, the type information headers (if added by the serializer) are removed by the deserializer.
120
120
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 earlier.
121
121
122
-
See also xref:tips.adoc#tip-json[Customizing the JsonSerializer and JsonDeserializer].
122
+
See also xref:tips.adoc#tip-json[Customizing the JacksonJsonSerializer and JacksonJsonDeserializer].
123
123
124
124
IMPORTANT: Starting with version 2.8, if you construct the serializer or deserializer programmatically as shown in xref:kafka/serdes.adoc#prog-json[Programmatic Construction], the above properties will be applied by the factories, as long as you have not set any properties explicitly (using `set*()` methods or using the fluent API).
125
125
Previously, when creating programmatically, the configuration properties were never applied; this is still the case if you explicitly set properties on the object directly.
@@ -409,7 +409,7 @@ Refer to the https://github.com/spring-projects/spring-retry[spring-retry] proje
409
409
== Spring Messaging Message Conversion
410
410
411
411
Although the `Serializer` and `Deserializer` API is quite simple and flexible from the low-level Kafka `Consumer` and `Producer` perspective, you might need more flexibility at the Spring Messaging level, when using either `@KafkaListener` or {spring-integration-url}/kafka.html[Spring Integration's Apache Kafka Support].
412
-
To let you easily convert to and from `org.springframework.messaging.Message`, Spring for Apache Kafka provides a `MessageConverter` abstraction with the `MessagingMessageConverter` implementation and its `JsonMessageConverter` (and subclasses) customization.
412
+
To let you easily convert to and from `org.springframework.messaging.Message`, Spring for Apache Kafka provides a `MessageConverter` abstraction with the `MessagingMessageConverter` implementation and its `JacksonJsonMessageConverter` (and subclasses) customization.
413
413
You can inject the `MessageConverter` into a `KafkaTemplate` instance directly and by using `AbstractKafkaListenerContainerFactory` bean definition for the `@KafkaListener.containerFactory()` property.
414
414
The following example shows how to do so:
415
415
@@ -443,15 +443,15 @@ With a class-level `@KafkaListener`, the payload type is used to select which `@
443
443
444
444
[NOTE]
445
445
====
446
-
On the consumer side, you can configure a `JsonMessageConverter`; it can handle `ConsumerRecord` values of type `byte[]`, `Bytes` and `String` so should be used in conjunction with a `ByteArrayDeserializer`, `BytesDeserializer` or `StringDeserializer`.
446
+
On the consumer side, you can configure a `JacksonJsonMessageConverter`; it can handle `ConsumerRecord` values of type `byte[]`, `Bytes` and `String` so should be used in conjunction with a `ByteArrayDeserializer`, `BytesDeserializer` or `StringDeserializer`.
447
447
(`byte[]` and `Bytes` are more efficient because they avoid an unnecessary `byte[]` to `String` conversion).
448
-
You can also configure the specific subclass of `JsonMessageConverter` corresponding to the deserializer, if you so wish.
448
+
You can also configure the specific subclass of `JacksonJsonMessageConverter` corresponding to the deserializer, if you so wish.
449
449
450
450
On the producer side, when you use Spring Integration or the `KafkaTemplate.send(Message<?> message)` method (see xref:kafka/sending-messages.adoc#kafka-template[Using `KafkaTemplate`]), you must configure a message converter that is compatible with the configured Kafka `Serializer`.
451
451
452
-
* `StringJsonMessageConverter` with `StringSerializer`
453
-
* `BytesJsonMessageConverter` with `BytesSerializer`
454
-
* `ByteArrayJsonMessageConverter` with `ByteArraySerializer`
452
+
* `StringJacksonJsonMessageConverter` with `StringSerializer`
453
+
* `BytesJacksonJsonMessageConverter` with `BytesSerializer`
454
+
* `ByteArrayJacksonJsonMessageConverter` with `ByteArraySerializer`
455
455
456
456
Again, using `byte[]` or `Bytes` is more efficient because they avoid a `String` to `byte[]` conversion.
457
457
@@ -513,7 +513,7 @@ public void projection(SomeSample in) {
513
513
Accessor methods will be used to lookup the property name as field in the received JSON document by default.
514
514
The `@JsonPath` expression allows customization of the value lookup, and even to define multiple JSON Path expressions, to look up values from multiple places until an expression returns an actual value.
515
515
516
-
To enable this feature, use a `ProjectingMessageConverter` configured with an appropriate delegate converter (used for outbound conversion and converting non-projection interfaces).
516
+
To enable this feature, use a `JacksonProjectingMessageConverter` configured with an appropriate delegate converter (used for outbound conversion and converting non-projection interfaces).
517
517
You must also add `spring-data:spring-data-commons` and `com.jayway.jsonpath:json-path` to the classpath.
518
518
519
519
When used as the parameter to a `@KafkaListener` method, the interface type is automatically passed to the converter as normal.
@@ -673,11 +673,11 @@ When using Spring Boot, this property name is `spring.kafka.consumer.properties.
673
673
[[payload-conversion-with-batch]]
674
674
== Payload Conversion with Batch Listeners
675
675
676
-
You can also use a `JsonMessageConverter` within a `BatchMessagingMessageConverter` to convert batch messages when you use a batch listener container factory.
676
+
You can also use a `JacksonJsonMessageConverter` within a `BatchMessagingMessageConverter` to convert batch messages when you use a batch listener container factory.
677
677
See xref:kafka/serdes.adoc[Serialization, Deserialization, and Message Conversion] and xref:kafka/serdes.adoc#messaging-message-conversion[Spring Messaging Message Conversion] for more information.
678
678
679
679
By default, the type for the conversion is inferred from the listener argument.
680
-
If you configure the `JsonMessageConverter` with a `DefaultJackson2TypeMapper` that has its `TypePrecedence` set to `TYPE_ID` (instead of the default `INFERRED`), the converter uses the type information in headers (if present) instead.
680
+
If you configure the `JacksonJsonMessageConverter` with a `DefaultJackson2TypeMapper` that has its `TypePrecedence` set to `TYPE_ID` (instead of the default `INFERRED`), the converter uses the type information in headers (if present) instead.
681
681
This allows, for example, listener methods to be declared with interfaces instead of concrete classes.
682
682
Also, the type converter supports mapping, so the deserialization can be to a different type than the source (as long as the data is compatible).
683
683
This is also useful when you use xref:kafka/receiving-messages/class-level-kafkalistener.adoc[class-level `@KafkaListener` instances] where the payload must have already been converted to determine which method to invoke.
For serializing and deserializing data when reading or writing to topics or state stores in JSON format, Spring for Apache Kafka provides a `JsonSerde` implementation that uses JSON, delegating to the `JsonSerializer` and `JsonDeserializer` described in xref:kafka/serdes.adoc[Serialization, Deserialization, and Message Conversion].
155
-
The `JsonSerde` implementation provides the same configuration options through its constructor (target type or `ObjectMapper`).
156
-
In the following example, we use the `JsonSerde` to serialize and deserialize the `Cat` payload of a Kafka stream (the `JsonSerde` can be used in a similar fashion wherever an instance is required):
154
+
For serializing and deserializing data when reading or writing to topics or state stores in JSON format, Spring for Apache Kafka provides a `JacksonJsonSerde` implementation that uses JSON, delegating to the `JacksonJsonSerializer` and `JacksonJsonDeserializer` described in xref:kafka/serdes.adoc[Serialization, Deserialization, and Message Conversion].
155
+
The `JacksonJsonSerde` implementation provides the same configuration options through its constructor (target type or `ObjectMapper`).
156
+
In the following example, we use the `JacksonJsonSerde` to serialize and deserialize the `Cat` payload of a Kafka stream (the `JacksonJsonSerde` can be used in a similar fashion wherever an instance is required):
157
157
158
158
[source,java]
159
159
----
160
-
stream.through(Serdes.Integer(), new JsonSerde<>(Cat.class), "cats");
160
+
stream.through(Serdes.Integer(), new JacksonJsonSerde<>(Cat.class), "cats");
161
161
----
162
162
163
163
When constructing the serializer/deserializer programmatically for use in the producer/consumer factory, since version 2.3, you can use the fluent API, which simplifies configuration.
0 commit comments