1. 概述
Kafka传输自定义的DTO对象时,不能像平时一样使用StringSerializer和StringDeserializer。这种情况需要自己实现对应DTO的序列化器和反序列化器。假设现在有个 KafkaMsgDto 类,代码如下:
@Data
public class KafkaMsgDto {
private String id;
private ActionEnum action;
public KafkaMsgDto(){
}
public KafkaMsgDto(String id, ActionEnum action){
this.id = id;
this.action = action;
}
public enum ActionEnum{
SAVE,
DELETE;
}
}
2. Serializer
public class KafkaMsgSerializer implements Serializer<KafkaMsgDto> {
private String encoding = "UTF8";
public KafkaMsgSerializer(){
}
@Override
public void configure(Map<String, ?> configs, boolean isKey) {
String propertyName = isKey ? "key.serializer.encoding" : "value.serializer.encoding";
Object encodingValue = configs.get(propertyName);
if (encodingValue == null) {
encodingValue = configs.get("serializer.encoding");
}
if (encodingValue instanceof String) {
this.encoding = (String)encodingValue;
}
}
@Override
public byte[] serialize(String s, KafkaMsgDto data) {
try {
if (data == null){
return null;
}
return JSON.toJSONString(data).getBytes(this.encoding);
} catch (UnsupportedEncodingException var4) {
throw new SerializationException("Error when serializing string to byte[] due to unsupported encoding " + this.encoding);
}
}
}
3. Deserializer
public class KafkaMsgDeserializer implements Deserializer<KafkaMsgDto> {
private String encoding = "UTF8";
public KafkaMsgDeserializer(){
}
public void configure(Map<String, ?> configs, boolean isKey) {
String propertyName = isKey ? "key.deserializer.encoding" : "value.deserializer.encoding";
Object encodingValue = configs.get(propertyName);
if (encodingValue == null) {
encodingValue = configs.get("deserializer.encoding");
}
if (encodingValue instanceof String) {
this.encoding = (String)encodingValue;
}
}
public KafkaMsgDto deserialize(String topic, byte[] data) {
try {
if (data == null){
return null;
}
return JSON.parseObject(new String(data, this.encoding), KafkaMsgDto.class);
} catch (UnsupportedEncodingException var4) {
throw new SerializationException("Error when deserializing byte[] to string due to unsupported encoding " + this.encoding);
}
}
}
4. application.properties
修改对应的序列化、反序列化配置
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=com.train.kafka.serialization.KafkaMsgSerializer
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=com.train.kafka.serialization.KafkaMsgDeserializer
5. 发送消息
KafkaMsgDto dto = new KafkaMsgDto(id, KafkaMsgDto.ActionEnum.SAVE);
kafkaTemplate.send("test-topic", dto);
6. 接收消息
@KafkaListener(topics = "test-topic")
public void onListener(KafkaMsgDto dto){
if (dto == null){
System.out.println("接收到空消息");
return;
}
System.out.println(String.format("接收到消息:%s", dto.toString()));
if (dto.getAction() == KafkaMsgDto.ActionEnum.DELETE){
//执行删除业务逻辑
}
else{
//执行保存业务逻辑
}
}