Десериализация POJO в потоках Кафки
В моей теме Кафка есть сообщения этого формата
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 следующим образом. Также мне нужен объект User для выполнения некоторых других функций.
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();
Я получаю ошибку ниже
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.
Я думаю, что я должен предоставить правильное Serde
для класса пользователя.
Кто-нибудь может направить меня в этом?
0 ответов
Проблема в значениях Serdes.
Существует две версии функции groupBy:
KStream::KGroupedStream<K, V> groupByKey();
KStream::KGroupedStream<K, V> groupByKey(final Grouped<K, V> grouped);
Первый вариант под капотом называют вторым с Grouped
с Serdes по умолчанию (В вашем случае это было для ключа и значения StringSerde
Ваш flatMap
отобразить сообщение на KeyValue<String, User>
тип, так что значение было типа User
,
Решение в вашем случае будет использовать вместо groupByKey()
вызов groupByKey(Grouped.with(keySerde, valSerde));
с надлежащими сердами.