【问题标题】:Recursively parsing a json file using Jackson Json parser使用 Jackson Json 解析器递归解析 json 文件
【发布时间】:2019-07-03 13:57:21
【问题描述】:

我正在尝试递归解析一个包含许多复杂元素集的示例 Json 文件。 我正在尝试的代码是这样的:

public class Jsonex {
    public static void main(String argv[]) {
        try {
            Jsonex jsonExample = new Jsonex();
           jsonExample.testJackson();
        } catch (Exception e){
            System.out.println("Exception " + e);
        }       
    }
    public static void testJackson() throws IOException {       
        JsonFactory factory = new JsonFactory();
       // System.out.println("hello");
        ObjectMapper mapper = new ObjectMapper(factory);
        File from = new File("D://albumList.txt");
        TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {};
        HashMap<String,Object> o= mapper.readValue(from, typeRef);
       // System.out.println("" + o);
        Iterator it = o.entrySet().iterator();
       while (it.hasNext()) {

          Map.Entry pairs = (Map.Entry)it.next();
            System.out.println(pairs.getKey() + " = " + pairs.getValue());

           HashMap<String,Object> o1=mapper.readValue(pairs.getValue().toString(),typeRef);
          System.out.println("hey"+o1);
           Iterator it1 = o1.entrySet().iterator();
           while (it1.hasNext()) {
                Map.Entry pairs1 = (Map.Entry)it.next();
                System.out.println(pairs1.getKey() + " = " + pairs1.getValue());
            it1.remove(); // avoids a ConcurrentModificat



    }   
    }
}}

我得到了这个例外:

异常 org.codehaus.jackson.JsonParseException:意外字符('i'(代码 105)):期待双引号开始字段名称 在 [来源:java.io.StringReader@2de7753a;行:1,列:3]

实际上我想做的是,解析文件并获取名称对象对的列表,然后获取具有名称对象对的对象。 - 但问题是解析器在字符串之前期待“”!

【问题讨论】:

  • 你能展示一些 JSON 吗?为什么无效?至少对于字段名称,您可以在 ObjectMapper 上配置 JsonParser.Feature ALLOW_UNQUOTED_FIELD_NAMES
  • {"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", " onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} } }} 非常感谢,但有一个新的异常。它说异常 org.codehaus.jackson.JsonParseException: Unexpected character ('=' (code 61)): was Expecting a冒号来分隔字段名称和值[来源:java.io.StringReader@2de7753a;行:1,列:5] 现在。请帮助我@nutlike
  • 当我询问 JSON 时,我的意思是 您的 JSON,而不是来自 json.org/example.html ...请相应地更新您的问题。除此之外(再次):为什么您的 JSON 无效?你从哪里得到它?
  • 这是我实际解析的json文件。我的程序将这个作为输入!
  • 好吧,我很困惑,因为所有字段都被正确引用 - 我错过了您代码中的第二个 mapper.readValue(…)。我添加了一个答案,可以帮助您重新思考/重新设计您的解决方案。

标签: json jackson


【解决方案1】:

您应该考虑使用 Jacksons 内置的树模型功能 (http://wiki.fasterxml.com/JacksonTreeModel),而不是自己解析所有内容:

ObjectMapper mapper = new ObjectMapper(factory);
File from = new File("D://albumList.txt");
JsonNode rootNode = mapper.readTree(from);  

Iterator<Map.Entry<String,JsonNode>> fields = rootNode.fields();
while (fields.hasNext()) {

    Map.Entry<String,JsonNode> field = fields.next();
    System.out.println(field.getKey() + " = " + field.getValue());
    …

}

从长远来看,这应该更方便。查看http://fasterxml.github.com/jackson-databind/javadoc/2.1.0/com/fasterxml/jackson/databind/JsonNode.html 的 API。

【讨论】:

  • 对不起,一旦我有了根节点,我仍然想找到一种方法来进行迭代。我对json完全陌生。我遇到的基本问题是我不知道元素名称先验@nutlike
  • @sreeraag:我更新了我的示例。如果您研究我的答案中链接的 API,我认为您应该能够找出缺失的部分。
  • 它仍然只在层次结构的一个级别上完成这项工作,不适用于多个级别,例如在上面的示例中,弹出窗口完全作为一个实体给出,但它本身就是一个复杂元素
  • recursion 与isArray()、isObject()、fields() 和elements() 结合使用。这是一项基本的编程任务……
  • 虽然它的答案很老,但即便如此我想更正 rootNode.fields(); 的调用到 rootNode.getFields();
【解决方案2】:

只是一个评论。如您所知,Jackson 支持 3 种主要处理模式(数据绑定、流式 API 和树模型)。您需要考虑到,如果您决定使用树模型,根据官方文档,内存使用量与映射的内容成正比(类似于数据绑定),因此树模型不能用于巨大的 Json 内容,除非映射是一次完成的。这与数据绑定遇到的问题相同;有时解决方案是使用 Stream-of-Events。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-11
    • 2018-06-30
    • 1970-01-01
    • 2011-05-05
    • 2020-05-31
    • 2018-09-30
    • 2012-07-05
    • 1970-01-01
    相关资源
    最近更新 更多