Java 反序列化卡夫卡流中的POJO

Java 反序列化卡夫卡流中的POJO,java,apache-kafka,pojo,apache-kafka-streams,Java,Apache Kafka,Pojo,Apache Kafka Streams,我的卡夫卡主题包含以下格式的消息 user1,subject1,80|user1,subject2,90 user2,subject1,70|user2,subject2,100 and so on. 我已经创建了用户POJO,如下所示 class User implements Serializable{ /** * */ private static final long serialVersionUID = -253687203767610477L; private St

我的卡夫卡主题包含以下格式的消息

user1,subject1,80|user1,subject2,90 

user2,subject1,70|user2,subject2,100 

and so on. 
我已经创建了用户POJO,如下所示

class User implements Serializable{
/**
 * 
 */
private static final long serialVersionUID = -253687203767610477L;
private String userId;
private String subject;
private String marks;

public User(String userId, String subject, String marks) {
    super();
    this.userId = userId;
    this.subject = subject;
    this.marks = marks;
}

public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}
public String getSubject() {
    return subject;
}
public void setSubject(String subject) {
    this.subject = subject;
}
public String getMarks() {
    return marks;
}
public void setMarks(String marks) {
    this.marks = marks;
}
}
此外,我还创建了默认键值序列化

streamProperties.put(
            StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
streamProperties.put(
            StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
我试图通过userID找到count,如下所示。我还需要用户对象来执行一些其他功能

KTable<String, Long> wordCount = streamInput

    .flatMap(new KeyValueMapper<String, String, Iterable<KeyValue<String,User>>>() {

        @Override
        public Iterable<KeyValue<String, User>> apply(String key, String value) {
            String[] userObjects = value.split("|");
            List<KeyValue<String, User>> userList = new LinkedList<>();
            for(String userObject: userObjects) {
                String[] userData = userObject.split(",");
                userList.add(KeyValue.pair(userData[0],
                        new User(userData[0],userData[1],userData[2])));


            }
            return userList;
        }
    })

.groupByKey()
.count();

我想我需要为用户类提供正确的
Serde

问题在于值Serde

函数groupBy有两个版本:

  • KStream::KGroupedStream groupByKey()
  • KStream::KGroupedStream groupByKey(最终分组)
第一个版本在引擎盖下调用第二个版本,使用
分组
和默认序列号(在您的情况下,它是用于键和值
StringSerde

您的
flatMap
将消息映射到
KeyValue
类型,因此值的类型为
User


您的解决方案是使用
groupByKey()
调用
groupByKey(Grouped.with(keySerde,valSerde))
,使用正确的Serdes。

您需要定义自己的反序列化器类。请展示您在这方面的尝试。同时找出生产者使用的反序列化器的定义位置,类UserDeserializer实现反序列化器将是一个好的开始。但是,您确定您的记录确实是字符串中的两个用户对象吗?可以吗您显示的控制台使用者输出最多有5条消息?@cricket_007否kafka中的每条消息都有许多用户对象的信息,这些信息用管道分隔符分隔。每条用户信息都用逗号分隔。请检查构造函数和每条用户消息。这就是我使用flatMapI的原因。我认为问题在于您的生产方式正在初始化消息并从Kafka队列中读取消息。两者都需要以相同的方式序列化。请尝试以String Serializable转换所有消息,然后运行您的代码。应该可以。如果可以,请尝试将其更改为正确的JSON序列化器,然后读取。在这种情况下,正确的valSerde是什么?
Caused by: org.apache.kafka.streams.errors.StreamsException: A serializer (key: org.apache.kafka.common.serialization.StringSerializer / value: org.apache.kafka.common.serialization.StringSerializer) is not compatible to the actual key or value type (key type: java.lang.String / value type: com.example.testing.dao.User). Change the default Serdes in StreamConfig or provide correct Serdes via method parameters.