web-dev-qa-db-fra.com

Envoyer des objets personnalisés Java à Kafka Topic

J'ai mon objet Java Java personnalisé et je souhaite utiliser la JVM dans la sérialisation intégrée pour l'envoyer à une rubrique Kafka, mais la sérialisation échoue avec l'erreur ci-dessous)

org.Apache.kafka.common.errors.SerializationException: impossible de convertir la valeur de la classe com.spring.kafka.Payload en classe org.Apache.kafka.common.serialization.ByteArraySerializer spécifié dans 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;
    }

}

Lors de ma création de producteur, j'ai les propriétés suivantes définies

<entry key="key.serializer"
                       value="org.Apache.kafka.common.serialization.ByteArraySerializer" />
                <entry key="value.serializer"
                       value="org.Apache.kafka.common.serialization.ByteArraySerializer" />

Mon appel d'envoi est comme ci-dessous

kafkaProducer.send(new ProducerRecord<String, Payload>("test", new Payload()));

Quelle est la bonne façon d'envoyer un objet Java Java personnalisé via un producteur à une rubrique kafka?

11
Vinod Jayachandran

Nous avons 2 options comme indiqué ci-dessous

1) Si nous avons l'intention d'envoyer des objets Java Java personnalisés au producteur, nous devons créer un sérialiseur qui implémente org.Apache.kafka.common.serialization.Serializer et passer cette classe Serializer lors de la création de votre producteur

Référence du code ci-dessous

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() {

    }
}

Et définissez le sérialiseur de valeur en conséquence

<entry key="value.serializer"
                       value="com.spring.kafka.PayloadSerializer" />

2) Pas besoin de créer une classe de sérialiseur personnalisée. Utilisez le ByteArraySerializer existant, mais pendant l'envoi, suivez le processus

Objet Java -> String (de préférence représentation JSON au lieu de toString) -> byteArray

14
Vinod Jayachandran

Puisque vous utilisez ByteArraySerializer, vous devez instancier un producteur d'octets [].

Producer<byte[],byte[]> producer = new KafkaProducer<>(props);

puis lors de la production, passez l'octet [] après la sérialisation ou une autre méthode, par exemple,

producer.send(new ProducerRecord<byte[],byte[]>("test", new Payload().toString().getBytes()));

Si vous passez juste un objet de charge utile au producteur, il sera préférable d'avoir un sérialiseur de clés et un sérialiseur de valeur comme tout ce que vous avez l'intention de passer et pendant la lecture, vous devez lire ces données.

Il est recommandé d'utiliser Serializable et ByteArraySerializer/ByteArrayDeserializer.

3
Abhishek Kumar