简体   繁体   English

使用流/对象方法将JSON解析为Jackson

[英]Parsing JSON into Jackson using a stream/object approach

I have a JSON file which can have multiple types. 我有一个JSON文件,可以有多种类型。

For example: 例如:

{
    "dog": {
        "owner" : "John Smith",
        "name" : "Rex",
        "toys" : {
            "chewtoy" : "5",
            "bone" : "1"
        }
    },
    "person": {
        "name" : "John Doe",
        "address" : "23 Somewhere Lane"
    }
    // Further examples of dogs and people, and a few other types.
}

I want to parse these into objects. 我想将它们解析为对象。 ie. 即。 I want to create a Dog object with owner/name/toys attributes, and person with name/address attributes, and use Jackson to read through and create objects out of them. 我想创建一个具有所有者/名称/玩具属性的Dog对象,以及具有名称/地址属性的人,并使用Jackson来读取并创建对象。

The ordering matters - I need to know that Rex came before John Doe, for example. 订购很重要 - 例如,我需要知道Rex来自John Doe。 I would prefer to do with a stream like approach (ie. read and parse Rex into the Dog object, do something with it, then discard it, then move onto to John Doe). 我更喜欢使用像流一样的方法(即读取并解析Rex到Dog对象中,用它做一些事情,然后丢弃它,然后转移到John Doe)。 So I need a stream based approach. 所以我需要一种基于流的方法。

I can't figure out how to use both the stream reading API (to go through in order) and the ObjectMapper interface (in order to create Java objects out of JSON) to accomplish this. 我无法弄清楚如何使用流读取API(按顺序进行)和ObjectMapper接口(以便用JSON创建Java对象)来实现这一目的。

To do this, you need to use an object mapper with your factory 为此,您需要在工厂中使用对象映射器

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.ObjectMapper;
...
private static ObjectMapper mapper = new ObjectMapper();
private static JsonFactory factory = mapper.getJsonFactory();

Then create a parser for the input. 然后为输入创建一个解析器。

JsonParser parser = factory.createJsonParser(in);

Now you can mix calls to parser.nextToken() and calls to parser.readValueAs(Class c) . 现在,您可以混合调用parser.nextToken()并调用parser.readValueAs(Class c) Here is an example that gets the classes from a map: 这是一个从地图中获取类的示例:

Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
classMap.put("dog", Dog.class);
classMap.put("person", Person.class);

InputStream in = null;
JsonParser parser = null;
List<Object> results = new ArrayList<Object>();
try {
  in = this.getClass().getResourceAsStream("input.json");
  parser = factory.createJsonParser(in);
  parser.nextToken();// JsonToken.START_OBJECT
  JsonToken token = null;
  while( (token = parser.nextToken()) == JsonToken.FIELD_NAME ) {
    String name = parser.getText();
    parser.nextToken(); // JsonToken.START_OBJECT
    results.add(parser.readValueAs(classMap.get(name)));
  }
  // ASSERT: token = JsonToken.END_OBJECT
}
finally {
  IOUtils.closeQuietly(in);
  try {
    parser.close();
  }
  catch( Exception e ) {}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM