我有自定义Java对象并且希望利用构建的序列化中的JVM将其发送到Kafka主题,但序列化失败并出现以下错误
org.apache.kafka.common.errors.SerializationException:无法转换 类com.spring.kafka.Payload的值到类 org.apache.kafka.common.serialization.ByteArraySerializer中指定 value.serializer
Payload.java
public class Payload implements Serializable {
private static final long serialVersionUID = 123L;
private String name="vinod";
private int anInt = 5;
private Double aDouble = new Double("5.0");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAnInt() {
return anInt;
}
public void setAnInt(int anInt) {
this.anInt = anInt;
}
public Double getaDouble() {
return aDouble;
}
public void setaDouble(Double aDouble) {
this.aDouble = aDouble;
}
}
在我创建生产者期间,我设置了以下属性
<entry key="key.serializer"
value="org.apache.kafka.common.serialization.ByteArraySerializer" />
<entry key="value.serializer"
value="org.apache.kafka.common.serialization.ByteArraySerializer" />
我的发送调用如下
kafkaProducer.send(new ProducerRecord<String, Payload>("test", new Payload()));
通过生产者将自定义java对象发送到kafka主题的正确方法是什么?
答案 0 :(得分:13)
我们有2个选项,如下所示
1)如果我们打算向生产者发送自定义java对象,我们需要创建一个实现 org.apache.kafka.common.serialization.Serializer 的序列化程序,并在创建期间传递该Serializer类。你的制片人
下面的代码参考
public class PayloadSerializer implements org.apache.kafka.common.serialization.Serializer {
public void configure(Map map, boolean b) {
}
public byte[] serialize(String s, Object o) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
byte[] b = baos.toByteArray();
return b;
} catch (IOException e) {
return new byte[0];
}
}
public void close() {
}
}
并相应地设置值序列化器
<entry key="value.serializer"
value="com.spring.kafka.PayloadSerializer" />
2)无需创建自定义序列化程序类。使用现有的ByteArraySerializer,但在发送过程中按照过程
Java对象 - &gt;字符串(优选JSON代表而不是 的toString) - &GT; ByteArray的
答案 1 :(得分:3)
由于您使用ByteArraySerializer
,因此需要实例化byte []生成器。
Producer<byte[],byte[]> producer = new KafkaProducer<>(props);
然后在序列化或其他方法生成后传递byte [],例如,
producer.send(new ProducerRecord<byte[],byte[]>("test", new Payload().toString().getBytes()));
如果您只是将一个Payload对象传递给生产者,那么最好将密钥序列化器和值序列化器作为您打算传递的内容,并且在阅读时您需要从该数据中读取。
最好使用Serializable和ByteArraySerializer / ByteArrayDeserializer。