]> juplo.de Git - demos/kafka/training/commitdiff
Serialisierung fachlicher Nachrichten mit dem `MessageConverter` springkafka/spring-producer--messageconverter springkafka/spring-producer--messageconverter--2026-06-lvm--rebase-vollständig
authorKai Moritz <kai@juplo.de>
Thu, 11 Jun 2026 15:39:11 +0000 (17:39 +0200)
committerKai Moritz <kai.milan.moritz@googlemail.com>
Fri, 12 Jun 2026 17:49:00 +0000 (19:49 +0200)
README.sh
build.gradle
docker/docker-compose.yml
pom.xml
src/main/java/de/juplo/kafka/AddNumberMessage.java [new file with mode: 0644]
src/main/java/de/juplo/kafka/ApplicationConfiguration.java
src/main/java/de/juplo/kafka/CalculateSumMessage.java [new file with mode: 0644]
src/main/java/de/juplo/kafka/ExampleProducer.java
src/main/java/de/juplo/kafka/SumupMessage.java [new file with mode: 0644]

index 04f0a01b4aa43703db35b69649c6442d842c8b3e..b9d8b8915acf3785a11b4fcb75af23448ed07b51 100755 (executable)
--- a/README.sh
+++ b/README.sh
@@ -1,6 +1,5 @@
 #!/bin/bash
-
-IMAGE=juplo/spring-producer:2.0-kafkatemplate-SNAPSHOT
+IMAGE=juplo/spring-producer:2.0-messageconverter-SNAPSHOT
 
 if [ "$1" = "cleanup" ]
 then
index f0fb593efdafd7c3c1aaea66e97a8b154290f564..947bbd3410df6cb609984d45431efcfb498a24ee 100644 (file)
@@ -6,7 +6,7 @@ plugins {
 }
 
 group = 'de.juplo.kafka'
-version = '2.0-kafkatemplate-SNAPSHOT'
+version = '2.0-messageconverter-SNAPSHOT'
 
 java {
        toolchain {
index bbb4352463dc468068f18a95eb8a7c1307437350..2720716823fdc3c36d45fb639792c6676dc8ab6a 100644 (file)
@@ -173,7 +173,7 @@ services:
       - kafka-3
 
   producer:
-    image: juplo/spring-producer:2.0-kafkatemplate-SNAPSHOT
+    image: juplo/spring-producer:2.0-messageconverter-SNAPSHOT
     environment:
       spring.kafka.bootstrap-servers: kafka:9092
       spring.kafka.client-id: producer
diff --git a/pom.xml b/pom.xml
index ec2f3f9218497043516f26f293108deeb46df87e..59131858196b7b51a98d6533f7c4e8d29743439e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -15,7 +15,7 @@
   <artifactId>spring-producer</artifactId>
   <name>Spring Producer</name>
   <description>A Simple Producer, based on the KafkaTemplate and Spring Boot, that sends messages via Kafka</description>
-  <version>2.0-kafkatemplate-SNAPSHOT</version>
+  <version>2.0-messageconverter-SNAPSHOT</version>
 
   <properties>
     <java.version>21</java.version>
diff --git a/src/main/java/de/juplo/kafka/AddNumberMessage.java b/src/main/java/de/juplo/kafka/AddNumberMessage.java
new file mode 100644 (file)
index 0000000..deb6350
--- /dev/null
@@ -0,0 +1,11 @@
+package de.juplo.kafka;
+
+import lombok.Value;
+
+
+@Value
+public class AddNumberMessage implements SumupMessage
+{
+  private final int number;
+  private final int next;
+}
index f7ad65941284ec5f17a65d40fab9c7a0ba7625fa..aac39623a971a19d3c8226ccdbe372e6d0b12e17 100644 (file)
@@ -6,8 +6,15 @@ import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.core.ProducerFactory;
+import org.springframework.kafka.support.converter.JacksonJsonMessageConverter;
+import org.springframework.kafka.support.converter.StringJacksonJsonMessageConverter;
+import org.springframework.kafka.support.mapping.DefaultJacksonJavaTypeMapper;
+import org.springframework.kafka.support.mapping.JacksonJavaTypeMapper;
 
 import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
 
 
 @Configuration
@@ -18,7 +25,7 @@ public class ApplicationConfiguration
   public ExampleProducer exampleProducer(
     @Value("${spring.kafka.client-id}") String clientId,
     ApplicationProperties properties,
-    KafkaTemplate<String, String> kafkaTemplate,
+    KafkaTemplate<String, SumupMessage> kafkaTemplate,
     ConfigurableApplicationContext applicationContext)
   {
     return
@@ -30,5 +37,35 @@ public class ApplicationConfiguration
           : properties.getProducerProperties().getThrottle(),
         kafkaTemplate,
         () -> applicationContext.close());
+
+  }
+
+  @Bean
+  public KafkaTemplate<String, SumupMessage> kafkaTemplate(
+    ProducerFactory<String, SumupMessage> producerFactory,
+    JacksonJsonMessageConverter jacksonJsonMessageConverter) {
+
+    KafkaTemplate<String, SumupMessage> template = new KafkaTemplate<>(producerFactory);
+    template.setMessageConverter(jacksonJsonMessageConverter);
+
+    return template;
+  }
+
+  @Bean
+  public StringJacksonJsonMessageConverter jacksonJsonMessageConverter()
+  {
+    StringJacksonJsonMessageConverter converter = new StringJacksonJsonMessageConverter();
+    DefaultJacksonJavaTypeMapper typeMapper = new DefaultJacksonJavaTypeMapper();
+
+    // Verwende eine einfache, kurze Type-ID anstatt FQN
+    typeMapper.setTypePrecedence(JacksonJavaTypeMapper.TypePrecedence.TYPE_ID);
+    Map<String, Class<?>> typeMappings = new HashMap<>();
+    typeMappings.put("ADD", AddNumberMessage.class);
+    typeMappings.put("CALC", CalculateSumMessage.class);
+    typeMapper.setIdClassMapping(typeMappings);
+
+    converter.setTypeMapper(typeMapper);
+
+    return converter;
   }
 }
diff --git a/src/main/java/de/juplo/kafka/CalculateSumMessage.java b/src/main/java/de/juplo/kafka/CalculateSumMessage.java
new file mode 100644 (file)
index 0000000..6aa0121
--- /dev/null
@@ -0,0 +1,11 @@
+package de.juplo.kafka;
+
+
+import lombok.Value;
+
+
+@Value
+public class CalculateSumMessage implements SumupMessage
+{
+  private final int number;
+}
index 1e0ec3e712c060597c0e5d8032fe58cfcaf01620..8f52ce4c324651f8aafab8187eb959c8f96e1d45 100644 (file)
@@ -3,6 +3,9 @@ package de.juplo.kafka;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.kafka.clients.producer.RecordMetadata;
 import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.support.KafkaHeaders;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
 
 import java.time.Duration;
 
@@ -13,7 +16,7 @@ public class ExampleProducer implements Runnable
   private final String id;
   private final String topic;
   private final Duration throttle;
-  private final KafkaTemplate<String, String> kafkaTemplate;
+  private final KafkaTemplate<String, SumupMessage> kafkaTemplate;
   private final Thread workerThread;
   private final Runnable closeCallback;
 
@@ -25,7 +28,7 @@ public class ExampleProducer implements Runnable
     String id,
     String topic,
     Duration throttle,
-    KafkaTemplate<String, String> kafkaTemplate,
+    KafkaTemplate<String, SumupMessage> kafkaTemplate,
     Runnable closeCallback)
   {
     this.id = id;
@@ -49,7 +52,12 @@ public class ExampleProducer implements Runnable
     {
       for (; running; i++)
       {
-        send(Long.toString(i%10), Long.toString(i));
+        int number = (int) i % 10;
+        SumupMessage message = (i % 7 == 0)
+          ? new CalculateSumMessage(number)
+          : new AddNumberMessage(number, (int)i);
+
+        send(Long.toString(number), message);
 
         if (throttle.isPositive())
         {
@@ -76,11 +84,17 @@ public class ExampleProducer implements Runnable
     }
   }
 
-  void send(String key, String value)
+  void send(String key, SumupMessage value)
   {
     final long sendRequested = System.currentTimeMillis();
 
-    kafkaTemplate.send(topic, key, value).whenComplete((result, e) ->
+    Message<SumupMessage> message = MessageBuilder
+      .withPayload(value)
+      .setHeader(KafkaHeaders.TOPIC, topic)
+      .setHeader(KafkaHeaders.KEY, key)
+      .build();
+
+    kafkaTemplate.send(message).whenComplete((result, e) ->
     {
       long sendRequestProcessed = System.currentTimeMillis();
       if (e == null)
diff --git a/src/main/java/de/juplo/kafka/SumupMessage.java b/src/main/java/de/juplo/kafka/SumupMessage.java
new file mode 100644 (file)
index 0000000..739efd1
--- /dev/null
@@ -0,0 +1,5 @@
+package de.juplo.kafka;
+
+public interface SumupMessage
+{
+}