Java 束json解析

Java 束json解析,java,json,apache-beam,Java,Json,Apache Beam,我正在尝试读取和解析ApacheBeam代码中的JSON文件 PipelineOptions options = PipelineOptionsFactory.create(); options.setRunner(SparkRunner.class); Pipeline p = Pipeline.create(options); PCollection<String> lines = p.apply("ReadMyFile", TextIO.read().from("/User

我正在尝试读取和解析ApacheBeam代码中的JSON文件

PipelineOptions options = PipelineOptionsFactory.create();
options.setRunner(SparkRunner.class);

Pipeline p = Pipeline.create(options);

PCollection<String> lines = p.apply("ReadMyFile", TextIO.read().from("/Users/xyz/eclipse-workspace/beam-project/myfirst.json"));
System.out.println("lines: " + lines);

有人能指导我如何解析
testdata
并从上面的JSON文件中获取内容,然后我需要使用Beam来流式传输数据吗?

首先,我认为处理“打印精美”的JSON是不可能的(或者至少是常见的)。相反,JSON数据通常从中摄取,因此您的输入文件应如下所示:

{"testdata":{"siteOwner":"xxx","siteInfo":{"siteID":"id_member","siteplatform":"web","siteType":"soap","siteURL":"www,}}}
{"testdata":{"siteOwner":"yyy","siteInfo":{"siteID":"id_member2","siteplatform":"web","siteType":"soap","siteURL":"www,}}}
在这之后,当你的代码在
行中时,你就有了一个“行流”。接下来,通过在
ParDo
中应用parse函数,您可以
map
将这个“行流”映射到“json流”:

static class ParseJsonFn extends DoFn<String, Json> {

  @ProcessElement
  public void processElement(ProcessContext c) {
    // element here is your line, you can whatever you want, parse, print, etc
    // this function will be simply applied to all elements in your stream
    c.output(parseJson(c.element()))
  }
}

PCollection<Json> jsons = lines.apply(ParDo.of(new ParseJsonFn()))  // now you have a "stream of JSONs"
静态类ParseJsonFn扩展DoFn{
@过程元素
公共void processElement(ProcessContext c){
//元素是您的行,您可以根据需要进行解析、打印等操作
//此函数将简单地应用于流中的所有元素
c、 输出(parseJson(c.element())
}
}
PCollection jsons=lines.apply(ParDo.of(new ParseJsonFn())//现在您有了一个“json流”

是的,现代JSON库允许您将完全任意的JSON和伪JSON流解析为对象流,而无需将整个文件加载到内存中

没有特别需要在一行中填充对象。事实上,在设计处理大数据的软件时,避免为批量处理数据保留大量内存是一种很好的设计实践,因为仅使用千字节内存就可以按需流式处理数据

看一看Baeldung的简短教程:

我将在这里介绍Baeldung文章代码的中心部分,因为这是一个很好的实践,以防网站宕机:

while (jParser.nextToken() != JsonToken.END_OBJECT) {
    String fieldname = jParser.getCurrentName();
    if ("name".equals(fieldname)) {
        jParser.nextToken();
        parsedName = jParser.getText();
    }

    if ("age".equals(fieldname)) {
        jParser.nextToken();
        parsedAge = jParser.getIntValue();
    }

    if ("address".equals(fieldname)) {
        jParser.nextToken();
        while (jParser.nextToken() != JsonToken.END_ARRAY) {
            addresses.add(jParser.getText());
        }
    }
}

在本例中,解析器从对象开始标记开始,然后继续解析该对象。在您的情况下,您希望在文件完成之前一直循环,因此在退出while循环之后,您将继续前进,直到找到一个
JsonToken.START\u对象,然后创建一个新对象,完成此解析例程,最后将该对象交给Apache Beam。

确定。为什么parseJson对我来说是未定义的?我需要添加正确的jar还是导入?@Stella是的,您需要选择JSON库:。它们都提供了
parseJson
函数的一些变体。也得到了这个错误:方法apply(ptTransferMok,对于您的示例代码,我必须选择哪个json库?Jackson还是?parseJson(c.element()正确?它仍然给出错误,因为“类型ApacheBeamPrototype.ParseJsonFn的方法parseJson(字符串)未定义”另一点是,我想使用Beam流式传输解析后的testdata内容。我可以使用JsonFactory和Jackson库解析JSON内容。如何将此传递给Beam?但是,我不能这样做。如果有人可以帮助,请分享您的想法。我可以使用anyJSON库吗?我可以使用JsonFactory和Jackson库解析JSON内容。如何把这个交给Beam?好的,在我回答这个问题之前,你能解释一下你的输入和输出要求吗?从我可以告诉你的问题中有一个嵌套的json。你希望输出解析字符串是什么样子的?因为没有它,你有太多可能的答案,可能不适合你的要求t是问题中提到的JSON,我想将“testdata”值和流解析为字符串。
while (jParser.nextToken() != JsonToken.END_OBJECT) {
    String fieldname = jParser.getCurrentName();
    if ("name".equals(fieldname)) {
        jParser.nextToken();
        parsedName = jParser.getText();
    }

    if ("age".equals(fieldname)) {
        jParser.nextToken();
        parsedAge = jParser.getIntValue();
    }

    if ("address".equals(fieldname)) {
        jParser.nextToken();
        while (jParser.nextToken() != JsonToken.END_ARRAY) {
            addresses.add(jParser.getText());
        }
    }
}