【问题标题】:How to send streamed json data as a key value pair into kafka consumer如何将流式 json 数据作为键值对发送到 kafka 消费者
【发布时间】:2018-12-07 05:53:00
【问题描述】:

我写了一个 jave 代码从本地文件系统中读取一个 json 数据,我想将该数据作为键值对发送

public static void main(String[] args) throws IOException 
{
        Stream<String> objec = Files.lines(Paths.get("path\\data.json"));


                String topicName="test";

                Properties props=new Properties();
                props.put("kafka.bootstrap.servers", "localhost:9092,localhost:9093");
                props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
                props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");


                KafkaProducer<String,String> sampleProducer= new KafkaProducer<String,String>(props);
                objec.forEach(f->{
                ProducerRecord<String, String> record = new ProducerRecord<String, String>(topicName,f);        
                sampleProducer.send(record);
                });
                sampleProducer.close();

但是当我运行这个将数据作为字符串发送给 kafkaconsumer 的程序时,我如何将 json 数据作为键值对发送给 kafka 消费者...

这里是示例 json 文件

{  
   "wifi_result":"1",
   "mic_result":"1",
   "video_result":"1",
   "touch_result":"1",
   "proximity_result":"1",
   "vibrator_result":"1",
   "power_key":"2",
   "accelerometer":"0",
   "earphone":"1",
   "memory_result":"1",
   "memory_internalSD":"1",
   "memory_internalSDSize":"25.0GB",
   "memory_externalSD":"0",
   "memory_externalSDSize":"",
   "memory_internalflash":"1",
   "memory_internalflashSize":"2.0GB",
   "vol_key_down":"0",
   "menu_key":"1",
   "headset_result":"1",

}

帮助将不胜感激...在此先感谢...

【问题讨论】:

  • 您正在将文件作为字符串而不是 json 对象读取。其次,如果您可以在这里使用实际和预期的数据结构对您的数据进行采样,它将为我们提供更多的洞察力来帮助您。
  • @AmithKumar 没有读取 JSON 文件..
  • 是的,我知道您正在读取一个 json 文件,但是当您在 java 类中读取时并没有将其解析为 json 对象,而是将其解析为字符串对象。请同时发布您预期的主题记录和实际的主题记录。
  • @AmithKumar 我只是想读取数据并发布到一些Kafka主题中,但是数据将是键值对??不是字符串..!
  • 解决了您的问题吗?

标签: java apache-kafka kafka-producer-api


【解决方案1】:

将json文件读取为JSonObject而不是字符串,然后将其发送到Kafka主题。我正在使用 gson 库进行解析(作为示例代码),但您可以选择任何您选择的 json 解析库。

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import java.io.FileReader;

public class Main {

    static Gson gson = new Gson();

    public static JsonObject readJSON(String filePath) throws Exception {
     JsonReader reader = new JsonReader(new FileReader(filePath));
     return gson.fromJson(reader, JsonObject.class);
    }

    public static void main(String[] args) throws IOException {

     String topicName = "test";

     Properties props = new Properties();
     props.put("kafka.bootstrap.servers", "localhost:9092,localhost:9093");
     props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
     props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");


     KafkaProducer < String, String > sampleProducer = new KafkaProducer < String, String > (props);
     ProducerRecord < String, String > record = new ProducerRecord < String, String > (topicName, readJSON("data.json").toString());
     sampleProducer.send(record);
     sampleProducer.close();
    }
}

另外,如果只需要读取文件并将其按原样发送到主题,而不处理任何内容。您可以一次性将整个文件作为字符串读取并发送,而不是逐行流式传输,这将保留数据的 json 结构:

    public static String readFileAsString(File file)
    throws IOException {
     InputStream fileInputStream = new FileInputStream(file);
     byte[] buffer = new byte[fileInputStream.available()];
     int length = fileInputStream.read(buffer);
     fileInputStream.close();
     return new String(buffer, 0, length);
    }

    ProducerRecord < String, String > record = new ProducerRecord < String, String > (topicName, readFileAsString(new File("data.json")));

更新:

要将 json 文件数据作为键值传递给 Kafka 主题,您仍然必须将文件解析为 json 对象,然后通过 json 属性进行流式传输。请查看下面的示例代码,我使用 Jacksons 将 json 文件解析为 Map 对象,然后通过其属性逐个发送到主题。

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

//read json file as map object
    private static Map<String, String> readJsonFileAsMap(File file) throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(file, new TypeReference<Map<String,String>>(){});
    }

//stream data as key value pair
        KafkaProducer<String,String> sampleProducer= new KafkaProducer<String,String>(props);
        readJsonFileAsMap(file).forEach((k,v)->{
            ProducerRecord<String, String> record = new ProducerRecord<String, String>("test",k,v);
            sampleProducer.send(record);
        });
        sampleProducer.close();

如果您使用控制台消费者来验证数据,请确保print.key=true,您也可以选择添加分隔符key.separator=:

kafka-console-consumer --bootstrap-server localhost:9092 --topic test --from-beginning --property "print.key=true" -property "key.separator=:"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 2020-07-16
    • 1970-01-01
    相关资源
    最近更新 更多