从Kafka请求java对象时出错

从Kafka请求java对象时出错,java,apache-kafka,deserialization,Java,Apache Kafka,Deserialization,我开始学习卡夫卡,现在, 我正在发送/接收序列化/理想化的java类。 我的问题是:我的配置中遗漏了什么,所以我无法从Kafka反序列化对象 这是我的班级: 我在主类中的属性: producerPropsObject.put(ProducerConfig.CLIENT\u ID\u CONFIG, AppConfigs.applicationProducerSerializedObject); producerPropsObject.put(ProducerConfig.BOOTSTRAP\u

我开始学习卡夫卡,现在, 我正在发送/接收序列化/理想化的java类。 我的问题是:我的配置中遗漏了什么,所以我无法从Kafka反序列化对象

这是我的班级:

我在主类中的属性:

producerPropsObject.put(ProducerConfig.CLIENT\u ID\u CONFIG, AppConfigs.applicationProducerSerializedObject); producerPropsObject.put(ProducerConfig.BOOTSTRAP\u SERVERS\u CONFIG, AppConfigs.bootstrapserver); producerPropsObject.put(ProducerConfig.KEY\u SERIALIZER\u CLASS\u CONFIG, StringSerializer.class.getName()); producerPropsObject.put(ProducerConfig.VALUE\u SERIALIZER\u CLASS\u CONFIG, FooSerializer.class.getName()); producerPropsObject.put(“主题”,AppConfigs.topicNameForSerializedObject)

consumerPropsObject.put(ConsumerConfig.GROUP\u ID\u CONFIG,AppConfigs.applicationProducerSerializedObject); consumerPropsObject.put(ConsumerConfig.BOOTSTRAP\u SERVERS\u CONFIG,AppConfigs.bootstrapsservers); consumerPropsObject.put(ConsumerConfig.KEY_反序列化程序_CLASS_CONFIG,StringDeserializer.CLASS.getName()); consumerPropsObject.put(ConsumerConfig.VALUE\u反序列化程序\u CLASS\u配置,FooDeserializer.CLASS.getName()); consumerPropsObject.put(ConsumerConfig.MAX\u POLL\u INTERVAL\u MS\u CONFIG,300000); consumerPropsObject.put(ConsumerConfig.ENABLE\u AUTO\u COMMIT\u CONFIG,true); consumerPropsObject.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,“最早”); consumerPropsObject.put(“主题”,AppConfigs.topicNameForSerializedObject)

以下是序列化程序/反序列化程序实现:

最后,我试图从main生产和消费我的食物的方式:

看起来,它很好用,因为我后来在卡夫卡主题中看到了我的键和值

public void producerobjecttokafka(最终属性producerProps){
最终字符串[]ar=新字符串[]{“矩阵”、“裸枪”、“第五元素”、“铁杆”、“乱世佳人”};
卡夫卡制作人=新卡夫卡制作人(producerProps);
final Foo j=新Foo(ar[getAnInt(4)],getAnInt(10),getAnDouble());
send(新的ProducerRecord(producerProps.getProperty(“主题”),j.getItem(),j.toString().getBytes());
producer.flush();
producer.close();
}
但是,当我的消费者捕获输出时:

public void ConsumerFoodFromKafka(最终属性ConsumerOps){
最终消费者支持者=新卡夫卡消费者(consumerProps);
最终螺纹分离螺纹=新螺纹(()->{
试一试{
myConsumer.subscribe(Collections.singletonList(consumerProps.getProperty(“主题”));
while(continueToRunFlag){
最终StringBuilder sb=新StringBuilder();
最终消费者记录消费者记录=myConsumer.poll(持续时间:百万分之十);
如果(consumerRecords.count()>0){
用于(消费记录cRec:消费记录){

sb.append(cRec.key()).append(我不知道为什么您使用bytearray outputstream,但试图在反序列化程序中读取JSON,但这解释了错误。您甚至可以通过直接调用serialize/deserialize方法,在根本不使用Kafka的情况下对其进行测试

在提供的链接中,序列化程序使用
objectMapper.writeValueAsString
,它返回JSON文本,而不是特定于Java的outputstream。如果您希望在不同的编程语言之间使用和生成数据(大多数公司都是这样),您应该避免这种特定的序列化格式


注意:Confluent为Kafka提供了Avro、Protobuf和JSON序列化程序,因此如果您想使用其中一种格式,您不需要编写自己的序列化程序。如果您想从JSON反序列化,那么您需要将其序列化为JSON,在您的序列化程序中也使用jackson,一切都应该很好

公共类FooSerializer实现org.apache.kafka.common.serialization.Serializer{
公共无效配置(映射,布尔b){}
公共字节[]序列化(字符串s,对象o){
试一试{
ObjectMapper om=new ObjectMapper();//来自jackson的ObjectMapper
字节[]b=om.writeValueAsString(o.getBytes();
返回b;
}catch(IOE异常){返回新字节[0];}
}
公共void close(){}
}

你也尝试过使用jackson进行序列化吗?没有,我只是遵循了一个在线示例……这里没有关于序列化失败的任何消息,因为你序列化的不是json的字节,而是你对象的字节,你需要序列化为json,这就是我建议使用jackson的原因serializer@rizesky不需要JSON,卡夫卡根本不在乎只要它是bytes@OneCricketeer这不是kafka的问题,请阅读问题,这是他的反序列化程序问题,kafka在其对象的字节流中接受他的消息,但不是json的字节,而是其java对象的字节,这取决于其对可序列化接口的实现(是否超出左默认值),这就是为什么他的json desealizer if无法反序列化,因为它需要字节的json来执行,但他提供了他的java对象的字节。如果您仍然不理解,请阅读什么是序列化。thanksAgree,他可能认为序列化正在创建该对象的json。serializaton只是创建序列化对象的字节序列我无法存储在磁盘中或通过socketGuys发送,非常感谢您的帮助…事实上,我错过了这两种不同的序列化方式…就像我说的:我刚刚开始。。。
public class Foo { 
    private String item;
    private int quantity;
    private Double price;
  
    public Foo(String item, int quantity, final double price) {
        this.item = item;
        this.quantity = quantity;
        this.price = price;
    }

    public String getItem() { return item; }
    public int getQuantity() { return quantity; }
    public Double getPrice() { return price; }

    public void setQuantity(int quantity) { this.quantity = quantity; }
    public void setPrice(double price) { this.price = price; }

    @Override
    public String toString() {
        return "item=" + item + ", quantity=" + quantity + ", price=" + price;
    }
}
public class FooSerializer 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() {  }
}

public class FooDeserializer implements org.apache.kafka.common.serialization.Deserializer {
    
    @Override
    public void close() { }

    @Override
    public Foo deserialize(String arg0, byte[] arg1) {
    
        //Option #1:
        //ObjectMapper mapper = new ObjectMapper();
        //Option #2:
        JsonFactory factory = new JsonFactory();
        factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
        ObjectMapper mapper = new ObjectMapper(factory);
        Foo fooObj = null;
        try {
            //Option #1:
            //fooObj = mapper.readValue(arg1, Foo.class);     // BREAKS HERE!!!
            //Option #2:
            fooObj = mapper.reader().forType(Foo.class).readValue(arg1); // BREAKS HERE!!!
    
        }
        catch (Exception e) { e.printStackTrace(); }
    
        return fooObj;
    }

}
public void produceObjectToKafka(final Properties producerProps) { 
    final String[] ar = new String[]{"Matrix", "Naked Gun", "5th Element", "Die Hard", "Gone with a wind"};
    KafkaProducer<String, byte[]> producer = new KafkaProducer<>(producerProps);
    final Foo j = new Foo(ar[getAnInt(4)], getAnInt(10), getAnDouble());
    producer.send(new ProducerRecord<>(producerProps.getProperty("topic"), j.getItem(), j.toString().getBytes()));
    producer.flush();   
    producer.close();
}
public void consumeFooFromKafka(final Properties consumerProps) {
    final Consumer<String, Foo> myConsumer = new KafkaConsumer<>(consumerProps);
    final Thread separateThread = new Thread(() -> {
        try {
            myConsumer.subscribe(Collections.singletonList(consumerProps.getProperty("topic")));
            while (continueToRunFlag) {
                final StringBuilder sb = new StringBuilder();
                final ConsumerRecords<String, Foo> consumerRecords = myConsumer.poll(Duration.ofMillis(10));
                if (consumerRecords.count() > 0) {
                    for (ConsumerRecord<String, Foo> cRec : consumerRecords) {
                        sb.append(  cRec.key()  ).append("<<").append(cRec.value().getItem() + ",").append(cRec.value().getQuantity() + ",").append(cRec.value().getPrice()).append("|");
                   }
               }
               if (sb.length() > 0) { System.out.println(sb.toString()); }
            }
        }
        finally {
            myConsumer.close();
        }
    });
    separateThread.start();
}