2014-10-10 60 views
1

我正在使用Java中的Jackson API处理JSON。我一直在这里和那里一起工作,但没有太深入。Jackson - 使用对象数组,附加和移除

目前,我正在寻找一种很好的方法来获取从POJO列表创建的JSON对象数组(通过流或字符串)并追加或删除POJO。在追加的情况下,重复检查并不是必须的。举一个简单的例子,让我们说我有这个数组从Java列表建有名为“场”单变量对象:

[{"field":"value"},{"field":"value2"}] 

而且我想追加同一类型的对象为“现场“设置为”value3“。我可以简单地将整个数组反序列化为Java对象列表,添加新对象,然后将其序列化回JSON,但感觉像是过度杀伤。如果我可以使用Jackson来简单地序列化新对象并将其附加到JSON数组的末尾,那将会更好。这同样适用于从阵列中删除现有的对象。

+1

一个模拟问题的位。你使用jackson作为对象追加它还是只编辑字符串?就我个人而言,我会坚持杰克逊而不是将两者结合起来。其快速 – TedTrippin 2014-10-10 16:05:11

+0

我不想直接操纵字符串。我一直在挖掘一些杰克逊的文档,但还有很多需要解决,我还没有找到如何直接与杰克逊进行这项操作。理想情况下,我可以将一个InputStream与Jackson包装起来,并将其直接写入OutputStream中,最后添加新对象或者在JSON在流之间传递时删除现有对象。 – user1017413 2014-10-10 16:12:21

回答

1

我已经找到了一种方法,但奇怪的是,它的速度是直接反序列化加add rese reseze方法的两倍,列表中有500个POJO,每个POJO有三个字段,只有更多对象会变得更糟。

ObjectMapper mapper = new ObjectMapper(); 
JsonParser parser = mapper.getJsonFactory().createJsonParser(input); 
JsonGenerator gen = mapper.getJsonFactory().createJsonGenerator(output, JsonEncoding.UTF8); 
gen.writeStartArray(); 
parser.nextToken(); 
while (parser.nextToken() == JsonToken.START_OBJECT) { 
    //gen.writeTree(parser.readValueAsTree()); 
    //parser.skipChildren(); 
    //EDIT: This is much faster as the only method in the loop: 
    gen.copyCurrentStructure(parser); 
} 
gen.writeTree(mapper.valueToTree(/*new Object to add*/); 
gen.writeEndArray(); 
gen.close(); 
parser.close(); 

即使我没有得到每个对象为一棵树,而是反复地移动它们作为字段/值,这是一个有点快,但仍比其他慢得多。这是预期的还是有更好的方式来处理它作为流数据而不是JSON到Java到JSON的批量方法?

编辑:啊哈!发现JsonGenerator可以从直接复制JsonParser的当前结构。在while循环中使用这个更快,现在已经使bruteforce方法相当多。

+0

是的,在进行值转换时(从树或POJO到/从树中)有一些隐藏的开销;所以从'JsonParser'直接复制到'JsonGeneraror'更有效率。这就是为什么您最初的想法(读入'List',追加,写入)或者使用Streaming API进行低级别设置是最好的方法。 – StaxMan 2014-10-10 21:34:46