kafka自定义序列化与反序列化

本文详细介绍了如何在Kafka中实现自定义的序列化和反序列化过程,包括序列化对象、序列化实现类的编写、producer生产者配置、反序列化实现类的设计以及consumer消费者的设置,最后展示了操作效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

序列化对象

package com.oldwang.custom_serializer;

import java.io.Serializable;

/**
 * @author oldwang
 */
public class User implements Serializable {

    private int id;
    private String name;

    public User() {
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

序列化实现类

package com.oldwang.custom_serializer;

import org.apache.kafka.common.serialization.Serializer;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Map;

/**
 * @author oldwang
 * 自定义序列化器
 */
public class CustomUserSerializer implements Serializer<User> {

    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {

    }

    @Override
    public byte[] serialize(String topic, User data) {
        if(data == null){
            return null;
        }
        byte[] id,name;
        try {
            if(data.getName() != null) {
                name = data.getName().getBytes("UTF-8");
            }else {
                name = new byte[0];
            }
            if(data.getId() >= 0){
                id = (data.getId()+"").getBytes("UTF-8");
            }else {
                id = new byte[0];
            }
            ByteBuffer buffer = ByteBuffer.allocate(4+4+name.length+id.length);
            buffer.putInt(id.length);
            buffer.put(id);
            buffer.putInt(name.length);
            buffer.put(name);
            return buffer.array();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

    @Override
    public void close() {

    }
}

producer生产者

package com.oldwang.custom_serializer;


import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.serialization.StringSerializer;

import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @author oldwang
 *
 */
public class CustomSerializerProducer {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Properties properties = new Properties();
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"localhost:9092");
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        //使用自定义序列化器
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,CustomUserSerializer.class.getName());
        KafkaProducer<String, User> producer = new KafkaProducer<>(properties);
        Future<RecordMetadata> future = producer.send(new ProducerRecord<>("user", new User(1, "oldwang")));
        String topic = future.get().topic();
        System.out.println(topic);
        producer.close();
    }
}

反序列化实现类

package com.oldwang.custom_serializer;

import org.apache.kafka.common.serialization.Deserializer;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Map;

/**
 * @author oldwang
 */
public class CustomUserDeserializer implements Deserializer<User> {
    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {

    }

    @Override
    public User deserialize(String topic, byte[] data) {
        if (data == null) {
            return null;
        }
        if (data.length < 8){
            throw  new RuntimeException("data length error");
        }
        //wrap可以把字节数组包装成缓冲区ByteBuffer
        ByteBuffer buffer = ByteBuffer.wrap(data);
        int idLen,nameLen;

        //get()从buffer中取出数据,每次取完之后position指向当前取出的元素的下一位,可以理解为按顺序依次读取
        idLen = buffer.getInt();
        byte[] idBytes = new byte[idLen];
        buffer.get(idBytes);

        nameLen = buffer.getInt();
        byte[] nameBytes = new byte[nameLen];
        buffer.get(nameBytes);

        int id = 0;
        String name = null;
        try {
            id = Integer.parseInt(new String(idBytes,"UTF-8"));
            name = new String(nameBytes,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new User(id,name);
    }

        @Override
    public void close() {

    }
}

consumer消费者

package com.oldwang.custom_serializer;

import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.time.Duration;
import java.util.Collections;
import java.util.Properties;


/**
 * @author oldwang
 */
public class CustomSerializerConsumer {

    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"localhost:9092");
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,CustomUserDeserializer.class.getName());
        properties.put(ConsumerConfig.GROUP_ID_CONFIG,"user");
        properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
        KafkaConsumer<String,User> consumer = new KafkaConsumer<>(properties);
        consumer.subscribe(Collections.singleton("user"));
        while (true){
            ConsumerRecords<String, User> records = consumer.poll(Duration.ofMillis(1000));
            records.forEach(record -> {
                User user = record.value();
                System.out.println(user.toString());
            });
        }
    }
}

效果图

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值