使用Jackson Json解析器递归解析JSON文件

4

我正在尝试递归解析一个包含许多复杂元素集的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



    }   
    }
}}

我遇到了这个异常:

Exception org.codehaus.jackson.JsonParseException: Unexpected character ('i' (code 105)): was expecting double-quote to start field name at [Source: java.io.StringReader@2de7753a; line: 1, column: 3]

实际上我想做的是解析文件并获取名称对象对列表,然后取出其中的对象,该对象又包含名称-对象对。但是问题在于解析器希望在字符串前面加上""!


你能展示一些JSON吗?为什么它无效?至少对于字段名称,你可以在ObjectMapper上配置JsonParser.Feature ALLOW_UNQUOTED_FIELD_NAMES - nutlike
{"menu": { "id": "file", "value": "文件", "popup": { "menuitem": [ {"value": "新建", "onclick": "创建新文档()"}, {"value": "打开", "onclick": "打开文档()"}, {"value": "关闭", "onclick": "关闭文档()"} ] } }}非常感谢,那个可以用了,但是现在出现了一个新的异常。它说 Exception org.codehaus.jackson.JsonParseException: Unexpected character ('=' (code 61)): was expecting a colon to separate field name and value at [Source: java.io.StringReader@2de7753a; line: 1, column: 5]。请帮我看看 @nutlike - sreeraag
当我要求JSON时,我指的是你的JSON,而不是来自http://json.org/example.html ...请相应地更新你的问题。除此之外(再次强调):为什么你的JSON无效?你从哪里得到它的? - nutlike
那是我实际解析的JSON文件.. 我的程序以此作为输入! - sreeraag
好的,我有点困惑,因为所有字段都被正确引用了 - 我在你的代码中错过了第二个 mapper.readValue(...)。我添加了一个答案,可能会帮助您重新思考/重新设计您的解决方案。 - nutlike
2个回答

5

不要自己解析所有内容,你应该考虑使用Jackson内置的树模型功能(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());
    …

}

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


抱歉,我仍然没有找到一种方法来迭代遍历根节点。我对JSON完全不熟悉。我面临的基本问题是我事先不知道元素名称。@nutlike - sreeraag
@sreeraag:我更新了我的示例。如果你研究我回答中链接的API,我认为你应该能够找出缺失的部分。 - nutlike
它仍然只能在一个层次结构上完成工作,无法处理多个层次结构,例如在上面的示例中,弹出窗口被视为一个整体,但它本身是一个复杂的元素。 - sreeraag
2
使用递归与isArray()、isObject()、fields()和elements()相结合。这是一个基本的编程任务... - nutlike
1
虽然这是一个相当老的答案,但我仍然想纠正rootNode.fields()的调用方式,应该改为rootNode.getFields()。 - Ankur Verma

4

一点评论。正如你所知,Jackson支持三种主要的处理模式(数据绑定,流API和树模型)。需要注意的是,如果你决定使用树模型,根据官方文档,内存使用量与映射的内容成比例(类似于数据绑定),因此在处理大型Json内容时不能使用树模型,除非将映射分块进行。这与数据绑定遇到的问题相同;有时候解决方案是使用事件流。


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