使用gson解析JSON

3
{
    "took": 6200,
    "timed_out": false,
    "_shards": {
        "total": 68,
        "successful": 68,
        "failed": 0
    },
    "hits": {
        "total": 110745094,
        "max_score": 1,
        "hits": []
    },
    "facets": {
        "pie": {
            "_type": "terms",
            "missing": 135,
            "total": 29349,
            "other": 26420,
            "terms": [
                {
                    "term": "165.130.136.210",
                    "count": 390
                },
                {
                    "term": "165.130.136.206",
                    "count": 381
                },
                {
                    "term": "205.138.114.8",
                    "count": 359
                },
                {
                    "term": "205.138.115.229",
                    "count": 334
                },
                {
                    "term": "165.130.136.208",
                    "count": 331
                },
                {
                    "term": "66.37.212.155",
                    "count": 283
                },
                {
                    "term": "209.67.71.137",
                    "count": 279
                },
                {
                    "term": "66.37.204.17",
                    "count": 201
                },
                {
                    "term": "64.28.92.213",
                    "count": 193
                },
                {
                    "term": "64.85.64.202",
                    "count": 178
                }
            ]
        }
    }
}

我正在尝试解析以下内容,我已经尝试使用Perl中的JSon和JSon.simple,以及Java中的gson等多个API,但都没有成功。

我想要解析出facets=>pie=>terms=>term和count两个值,请问有人可以给我一个提取这两个值的提示吗?

以下是我目前的代码:

    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class TrueIPMonitor {

    public static void main(String[] args) {

        String json = getJson();
        System.out.println(json);
        System.out.println(parse(json));

    }

    public static String parse(String jsonLine) {
        JsonElement jelement = new JsonParser().parse(jsonLine);
        JsonObject jobject = jelement.getAsJsonObject();
        jobject = jobject.getAsJsonObject("facets");
        JsonArray jarray = jobject.getAsJsonArray("pie");
        jobject = jarray.get(0).getAsJsonObject();
        String result = jobject.get("terms").toString();
        return result;
    }

    public static String getJson() {
        BufferedReader br;
        String json = "";
        try {

            br = new BufferedReader(new FileReader("script/curlJson.log"));
            StringBuilder sb = new StringBuilder();
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                sb.append('\n');
                line = br.readLine();
            }
            json = sb.toString();

            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return json;

    }
}


{ "took" : 6200, "timed_out" : false, "_shards" : { "total" : 68, "successful" : 68, "failed" : 0 }, "hits" : { "total" : 110745094, "max_score" : 1.0, "hits" : [ ] }, "facets" : { "pie" : { "_type" : "terms", "missing" : 135, "total" : 29349, "other" : 26420, "terms" : [ { "term" : "165.130.136.210", "count" : 390 }, { "term" : "165.130.136.206", "count" : 381 }, { "term" : "205.138.114.8", "count" : 359 }, { "term" : "205.138.115.229", "count" : 334 }, { "term" : "165.130.136.208", "count" : 331 }, { "term" : "66.37.212.155", "count" : 283 }, { "term" : "209.67.71.137", "count" : 279 }, { "term" : "66.37.204.17", "count" : 201 }, { "term" : "64.28.92.213", "count" : 193 }, { "term" : "64.85.64.202", "count" : 178 } ] } } }

Exception in thread "main" java.lang.ClassCastException: com.google.gson.JsonObject cannot be cast to com.google.gson.JsonArray
    at com.google.gson.JsonObject.getAsJsonArray(JsonObject.java:172)
    at com.xxx.perf.monitor.TrueIPMonitor.parse(TrueIPMonitor.java:36)
    at com.xxx.perf.monitor.TrueIPMonitor.main(TrueIPMonitor.java:28)

你目前尝试过什么?你主要希望使用哪种编程语言? - Andrew Martin
如果您不向我们展示您的代码,我们就无法告诉您哪里出了问题。 - ikegami
@Tom:请删除你的评论并将代码添加到问题中(这样更容易阅读)。 - Andrew Martin
@Tom:我假设你已经下载了相关的库? - Andrew Martin
是的,我已经下载了库。我只需要更多地了解对象、数组与映射到我提供的 JSON 字符串之间的关系。 - Tom
3个回答

3

您的JSON格式正确。这里是一个Perl代码片段,可以打印出所有术语和计数:

...;
my $json = decode_json $input;

for my $term (@{ $json->{facets}{pie}{terms} }) {
    printf "%15s: %s\n", @$term{qw/term count/};
}

输出:

165.130.136.210: 390
165.130.136.206: 381
  205.138.114.8: 359
205.138.115.229: 334
165.130.136.208: 331
  66.37.212.155: 283
  209.67.71.137: 279
   66.37.204.17: 201
   64.28.92.213: 193
   64.85.64.202: 178

您的Java代码问题在于条目没有指向JSON数组,而是包含一个JSON对象。

facets : object
 `- pie : object
     `- terms : array

你可能想要的是(未经测试且有争议的风格):
public static String parse(String jsonLine) {
    JsonObject root = new JsonParser().parse(jsonLine).getAsJsonObject();
    JsonArray terms = root.getAsJsonObject("facets").getAsJsonObject("pie").getAsJsonArray("terms")
    JsonOject firstTerm = terms.get(0).getAsJsonObject();
    String result = firstTerm.get("terms").toString();
    return result;
}

2

gson

    public static void main(String[] args) {

    String json = getJson();
    System.out.println(json);
    parse(json);

}

public static void parse(String jsonLine) {
    JsonObject root = new JsonParser().parse(jsonLine).getAsJsonObject();
    JsonArray terms = root.getAsJsonObject("facets").getAsJsonObject("pie")
            .getAsJsonArray("terms");

    for (int i = 0; i < terms.size(); i++) {
        JsonObject term = terms.get(i).getAsJsonObject();
        System.out.printf("%s - %s \n", term.get("term").toString(), term.get("count").toString());
    }

}

Perl

my $json = decode_json $input;

for my $term (@{ $json->{facets}{pie}{terms} }) {
    printf "%15s: %s\n", @$term{qw/term count/};
}

以上两种方法对我都有效,感谢你的帮助。

0
JsonArray jarray = jobject.getAsJsonArray("pie");

"pie" 是一个对象,但你正在将它作为数组访问。 首先应该获取 "pie" 对象,然后是数组 "terms"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接