工具类

负责对象字节数组的相互转换,传输数据用

package com.yq.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class BeanUtil {
    /**
     * @Description 对象转字节数组
     * @param obj Object对象
     * @return byte[] 字节数组
     * @author SUNBIN
     * @date 2017年9月8日
     */
    public static byte[] ObjectToBytes(Object obj){
        byte[] bytes = null;
        ByteArrayOutputStream bo = null;
        ObjectOutputStream oo = null;
        try {
            bo = new ByteArrayOutputStream();
            oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);
            bytes = bo.toByteArray();

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(bo!=null){
                    bo.close();
                }
                if(oo!=null){
                    oo.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }

    /**
     * @Description 字节数组转对象
     * @param bytes 字节数组
     * @return Object Object对象
     * @author SUNBIN
     * @date 2017年9月8日
     */
    public static Object BytesToObject(byte[] bytes){
        Object obj = null;
        ByteArrayInputStream bi = null;
        ObjectInputStream oi = null;
        try {
            bi =new ByteArrayInputStream(bytes);
            oi =new ObjectInputStream(bi);
            obj = oi.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(bi!=null){
                    bi.close();
                }
                if(oi!=null){
                    oi.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }
}

消息实体类

需要继承Serializable接口和Encoder<MsgEntity>接口,并且实现构造函数MsgEntity(VerifiableProperties verifiableProperties),否则会报错无法运行起来

package com.yq.dto;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import kafka.serializer.Encoder;
import kafka.utils.VerifiableProperties;

/**
 * @Description kafka传递图片url消息实体类*/
public class MsgEntity implements Serializable, Encoder<MsgEntity>{
    private static final long serialVersionUID = 4948961384423258719L;
    /**图片id*/
    private int id;
    /**图片url*/
    private String url;

    /**
     * 构造函数
     * @param id 图片id
     * @param url 图片url
     */
    public MsgEntity(int id, String url){
        this.id = id;
        this.url = url;
    }
    /**
     * 构造函数,kafka支持
     * @param verifiableProperties
     */
    public MsgEntity(VerifiableProperties verifiableProperties){} 

    /**
     * 实现kafka实体类转换字节数组接口
     */
    @Override
    public byte[] toBytes(ImgUrlMessage entity) {return BeanUtil.ObjectToBytes(entity);
    }

    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}

Producer

设置Producer的"serializer.class"指定为MsgEntity.class.getName()

package com.kafka;

import java.util.Properties;
import java.util.concurrent.TimeUnit;

import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
import kafka.serializer.StringEncoder;

public class ProducerDemo extends Thread{
    //指定具体的topic
    private String topic;

    //构造函数
    public ProducerDemo(String topic){
        this.topic = topic;
    }

    @SuppressWarnings({ "deprecation", "unchecked", "rawtypes" })
    public void run(){
        //创建一个producer对象
        Producer producer = createProducer();
        int i=0;
        while(true){
            //使用producer发送数据
            producer.send(new KeyedMessage<Integer, Object>(this.topic, new MsgEntity(i, "www.baidu.com?id="+i)));
            System.out.println("Producer发送数据:" + i);
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
        }
    }

    @SuppressWarnings({ "deprecation", "rawtypes" })
    private Producer createProducer(){
        Properties prop = new Properties();
        //声明zk
        prop.put("zookeeper.connect", "node1.sunny.cn:2181,node2.sunny.cn:2181,node3.sunny.cn:2181");
        // 指定message的序列化方法,用户可以通过实现kafka.serializer.Encoder接口自定义该类
        // 默认情况下message的key和value都用相同的序列化,但是可以使用"key.serializer.class"指定key的序列化
        prop.put("serializer.class", MsgEntity.class.getName());
        // broker的地址
        prop.put("metadata.broker.list", "node1.sunny.cn:9092,node2.sunny.cn:9092,node3.sunny.cn:9092");
        // 这个参数用于通知broker接收到message后是否向producer发送确认信号
        //  0 - 表示producer不用等待任何确认信号,会一直发送消息,否则producer进入等待状态
        // -1 - 表示leader状态的replica需要等待所有in-sync状态的replica都接收到消息后才会向producer发送确认信号,再次之前producer一直处于等待状态
        prop.put("request.required.acks", "1");

        prop.put("producer.type", "async");
        prop.put("batch.num.messages", "5");
        return new Producer(new ProducerConfig(prop));
    }

    public static void main(String[] args) {
        new ProducerDemo("demo").start();
    }
}

Consumer

package com.kafka;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector;

public class ConsumerDemoOffsetA extends Thread {
    // 指定具体的topic
    private String topic;

    // 构造函数
    public ConsumerDemoOffsetA(String topic) {
        this.topic = topic;
    }

    @SuppressWarnings("deprecation")
    public void run(){
        try{
            //构建consumer对象
            ConsumerConnector consumer =createConsumer();
            //构建一个map对象,代表topic-------String:topic名称,Integer:从这个topic中获取多少条记录
            Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
            //每次获取1条记录
            topicCountMap.put(this.topic, 1);
            //构造一个messageStreams:输入流      --String:topic名称,List获取的数据
            Map<String, List<KafkaStream<byte[], byte[]>>> messageStreams = consumer.createMessageStreams(topicCountMap);
            //获取每次接收到的具体数据
            KafkaStream<byte[], byte[]> stream = messageStreams.get(this.topic).get(0);
            ConsumerIterator<byte[], byte[]> iterator = stream.iterator();
            while(iterator.hasNext()){
                byte[] data = iterator.next().message();
                ByteArrayInputStream ba = new ByteArrayInputStream(data);
                ObjectInputStream os = new ObjectInputStream(ba);
                MsgEntity entity = (MsgEntity) BeanUtil.BytesToObject(iterator.next().message());

                consumer.commitOffsets();
                System.out.println("ConsumerA接收到的数据:" + entity.getUrl());
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

    }

    //创建具体的Consumer
    @SuppressWarnings("deprecation")
    private ConsumerConnector createConsumer(){
        Properties prop = new Properties();
        //声明zk
        prop.put("zookeeper.connect", "node1.sunny.cn:2181,node2.sunny.cn:2181,node3.sunny.cn:2181");
        //指定这个consumer的消费组,每个组只能获取一次消息
        prop.put("group.id", "group1");
        //smallest和largest(默认)
        //此配置参数表示当此groupId下的消费者,在ZK中没有offset值时(比如新的groupId,或者是zk数据被清空),
        //consumer应该从哪个offset开始消费.
        //largest表示接受接收最大的offset(即最新消息),
        //smallest表示最小offset,即从topic的开始位置消费所有消息.
        prop.put("auto.offset.reset", "smallest");
        return Consumer.createJavaConsumerConnector(new ConsumerConfig(prop));
    }

    public static void main(String[] args) {
        new ConsumerDemoOffsetA("demo").start();
    }
}

【传输对象】kafka传递实体类消息的更多相关文章

  1. android activity传递实体类对象

    通过实现Parcelable接口序列化对象的步骤: 1.实现Parcelable接口.2.并且实现Parcelable接口的public void writeToParcel(Parcel dest, ...

  2. MVC -- 后台RedirectToAction传递实体类与字符串

    1.MVC -- 后台RedirectToAction传递实体类 RedirectToAction(控制器,控制器方法,实体类) 2.MVC -- 后台RedirectToAction传递字符串 Re ...

  3. SSM与jsp传递实体类

    jsp传controller Controller: @RequestMapping({"/user"}) public void registerUser(User uu) th ...

  4. hibernate sql查询后对象转换成实体类

    在多表查询的时候使用hibernate的sql查询的时候,一般返回的是object[]数组,或者可以使用  session.createSQLQuery(sql).setResultTransform ...

  5. C#调用webservice 时如何传递实体对象

    在webservice端公开一个实体类,然后实例化,赋值,然后再给到webservice,可以实现,但是,即使调用端和service端的实体类完全一致,你也要重新实例化service端的,重新赋值,将 ...

  6. JSON-JSON字符串转换成JSON对象、JSON对象数组、java实体类以及保存到List列表中

    处理JSON字符串时,一直出错,写个样例后发现原来是没有弄清楚数据的格式问题. 实现的是 JSONString 转换成java对象 或是 list列表 实例类 News package lyx.ent ...

  7. .NET解析xml字符串,通过反射给实体类对象赋值,获取实体类数据列表

    /// <summary> /// 解析xml字符串 转换为实体类列表数据 /// </summary> /// <param name="xmlStr&quo ...

  8. c#自定义ORM框架---(泛型&反射&实体类扩展属性<附带通用增、删、查、改>)

    该教材主要是运用到泛型.反射和实体类扩展属性 步骤一.建立扩展属性类 实体类扩展属性要继承Attribute基类完成 [AttributeUsage(AttributeTargets.Property ...

  9. C#中怎样连接数据库并将查询结果转为实体类以及如何加入事务

    场景 新建一个程序,需要对数据的表进行查询并将查询结果转换为实体类,然后将多个实体类 再插入到另一个数据库的表中,执行插入的过程中要使用事务. 注: 博客主页: https://blog.csdn.n ...

随机推荐

  1. 【python-opencv】22-直方图

    直方图目录: 22.1 直方图的计算,绘制与分析 22.1.1 统计直方图 22.1.2 绘制直方图 22.1.3 使用掩膜(遮罩) 22.2 直方图均衡化 22.2.1 OpenCV中的直方图均衡化 ...

  2. Java bytesToHexString 解析

    一.代码 /** * Convert byte[] to hex string * * @param src byte[] data * @return hex string */ public st ...

  3. oracle(九)索引扫描

    (1)索引唯一扫描(index unique scan) (2)索引范围扫描(index range scan) (3)索引全扫描(index full scan) (4)索引快速扫描(index f ...

  4. 【Python虫师】多窗口定位

    <注意>iframe框架 iframe也称作嵌入式框架,嵌入式框架和框架网页类似,它可以把一个网页的框架和内容嵌入在现有的网页中. 框架(framework)是一个基本概念上的结构,用于去 ...

  5. css3写等腰三角形

    <style>            .test {                width: 0;                height: 0;                b ...

  6. sql server 2005 使用Log Explorer查看和恢复数据

    使用Log Explorer查看和恢复数据    Log Explorer 4.1.可用于SQL Server2005的日志查看工具   下载地址: http://download.csdn.net/ ...

  7. plsql的sql窗口中文模糊查询没有作用

    环境变量新增: NLS_LANG = AMERICAN_AMERICA.AL32UTF8

  8. selenium python 启动Firefox

    我的火狐浏览器版本是最新的: 下载geckodrive:https://github.com/mozilla/geckodriver/releases/ 下载完后将exe文件放到这里“D:\firef ...

  9. c++移动构造函数

    写在前面 C++中有“左值”.“右值”的概念,C++11以后,又有了“左值”.“纯右值”.“将亡值”的概念.关于这些概念,许多资料上都有介绍,本文在拾人牙慧的基础上又加入了一些自己的一些理解,同时提出 ...

  10. tfs代码上传到server并下载到新位置

    1.svn与git代码管理原理基本一致,基于文档管理,能看到文件代码,通过设置文件的只读属性来控制代码. 而tfs是基于sqlserver及lock来管理,看不见代码文件 2.tfs没有自己的用户管理 ...