我有一个JSON文件,可以有多种类型。
例如:
{
"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.
}
我想将它们解析为对象。即。我想创建一个具有所有者/名称/玩具属性的Dog对象,以及具有名称/地址属性的人,并使用Jackson来读取并创建其中的对象。
订购很重要 - 例如,我需要知道Rex来自John Doe。我更喜欢使用像流一样的方法(即读取并解析Rex到Dog对象中,用它做一些事情,然后丢弃它,然后转移到John Doe)。所以我需要一种基于流的方法。
我无法弄清楚如何使用流读取API(按顺序进行)和ObjectMapper接口(以便用JSON创建Java对象)来完成此任务。
答案 0 :(得分:10)
为此,您需要在工厂中使用对象映射器
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();
然后为输入创建一个解析器。
JsonParser parser = factory.createJsonParser(in);
现在您可以混合调用 parser.nextToken()并调用 parser.readValueAs(Class c)。这是一个从地图中获取类的示例:
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 ) {}
}