Spring Boot 使用 KafkaTemplate 发送/接收 XML 格式消息 完整教程
这是企业级通用方案: Spring Boot 发送 Java对象 → XML字符串,接收 XML字符串 → Java对象,全程自动转换,无需手动拼接/解析XML。
一、核心原理
- 生产者:使用 XmlSerializer 把对象自动转 XML 发送
- 消费者:使用 XmlDeserializer 把 XML 自动转回对象
- 依赖 Jackson XML 实现转换(Spring 生态标准)
二、完整步骤(直接复制可用)
1. 新增 XML 依赖(必须)
Kafka 本身不带 XML 序列化器,需要添加 Jackson XML 依赖:
<dependencies>
<!-- Kafka 核心依赖 -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<!-- XML 序列化/反序列化核心依赖(必须) -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
</dependencies>
2. application.yml 配置(关键:XML 序列化)
spring:
kafka:
bootstrap-servers: localhost:9092
# 生产者:发送 XML
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
# 自定义 XML 序列化器
value-serializer: com.example.demo.config.KafkaXmlSerializer
acks: 1
# 消费者:接收 XML
consumer:
group-id: xml-group
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
# 自定义 XML 反序列化器
value-deserializer: com.example.demo.config.KafkaXmlDeserializer
auto-offset-reset: earliest
3. 创建 XML 序列化/反序列化器(通用工具类)
创建配置类,实现 Kafka 序列化接口:
package com.example.demo.config;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.kafka.common.serialization.Serializer;
import java.nio.charset.StandardCharsets;
// XML 序列化器:对象 → XML 字节数组
public class KafkaXmlSerializer implements Serializer<Object> {
private final XmlMapper xmlMapper = new XmlMapper();
@Override
public byte[] serialize(String topic, Object data) {
try {
return xmlMapper.writeValueAsBytes(data);
} catch (Exception e) {
throw new RuntimeException("XML 序列化失败", e);
}
}
}
package com.example.demo.config;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.kafka.common.serialization.Deserializer;
import java.nio.charset.StandardCharsets;
// XML 反序列化器:XML 字节数组 → 对象
public class KafkaXmlDeserializer implements Deserializer<Object> {
private final XmlMapper xmlMapper = new XmlMapper();
@Override
public Object deserialize(String topic, byte[] data) {
try {
return xmlMapper.readValue(data, Object.class);
} catch (Exception e) {
throw new RuntimeException("XML 反序列化失败", e);
}
}
}
4. 创建消息实体类(支持 XML 注解)
可以用 JAXB 注解美化 XML 结构:
package com.example.demo.entity;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
// XML 根节点
@JacksonXmlRootElement(localName = "UserMessage")
public class UserMessage {
private Long id;
private String name;
private Integer age;
private String content;
// 必须有无参构造
public UserMessage() {}
// getter & setter
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
@Override
public String toString() {
return "UserMessage{id=" + id + ", name='" + name + "'}";
}
}
5. 生产者:发送 XML 消息
直接传对象,自动转 XML 发送:
package com.example.demo.producer;
import com.example.demo.entity.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class XmlKafkaProducer {
@Autowired
private KafkaTemplate<String, UserMessage> kafkaTemplate;
private static final String TOPIC = "xml-topic";
@GetMapping("/send-xml")
public String sendXmlMessage() {
// 构建对象
UserMessage user = new UserMessage();
user.setId(1002L);
user.setName("李四");
user.setAge(28);
user.setContent("Spring Boot 发送 XML 消息");
// 直接发送对象 → 自动转 XML
kafkaTemplate.send(TOPIC, user);
return "XML 消息发送成功:" + user;
}
}
6. 消费者:接收 XML 自动转对象
直接接收 Java 对象,无需手动解析 XML:
package com.example.demo.consumer;
import com.example.demo.entity.UserMessage;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;
@Service
public class XmlKafkaConsumer {
private static final String TOPIC = "xml-topic";
// 直接接收 UserMessage 对象
@KafkaListener(topics = TOPIC, groupId = "xml-group")
public void consumeXmlMessage(UserMessage userMessage) {
System.out.println("==========================");
System.out.println("收到 XML 消息:");
System.out.println("对象:" + userMessage);
System.out.println("姓名:" + userMessage.getName());
System.out.println("内容:" + userMessage.getContent());
System.out.println("==========================");
}
}
三、先创建 Topic(必须)
./bin/kafka-topics.sh --create --topic xml-topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
四、测试运行
- 启动 Spring Boot
- 浏览器访问:
http://localhost:8080/send-xml
- 控制台输出:
收到 XML 消息:
对象:UserMessage{id=1002, name='李四'}
姓名:李四
内容:Spring Boot 发送 XML 消息
五、实际发送到 Kafka 的 XML 格式示例
<UserMessage>
<id>1002</id>
<name>李四</name>
<age>28</age>
<content>Spring Boot 发送 XML 消息</content>
</UserMessage>
六、常见问题
- 缺少 XML 依赖报错 必须添加
jackson-dataformat-xml - 反序列化失败 确保实体类有无参构造函数
- 收不到消息 检查 Topic 名称、消费者组、Kafka 状态
极简总结
- 依赖:jackson-dataformat-xml
- 配置:自定义 XML 序列化/反序列化器
- 发送:直接传对象 → 自动转 XML
- 接收:直接接收对象 → 自动解析 XML
完全适配 Spring Boot + Kafka 标准用法!