引言
继《Jackson快速入门》之后的高级相关操作。
Jackson提供了一种对于性能要求应用程序操作json更加高效的方式——流式API,这种方式开销小,性能高,因此,如果应用程序或者程序逻辑对于性能有一定要求,可以使用这种方式来进行json文件的读写操作,而对于一般的读写,使用普通的databind api即可。
要点
1、与Java8的“流式”概念不同,这种Jackson的这种流式是属于IO流,在写出与读入的最后都要进行流的关闭 —— close()。
2、这种流式API(Streaming APIs),是一种高性能(high-performance)读写JSON的方式,同时也是一种增量模式(incremental mode)。
3、Token概念:使用流式API的时候,每一个JSON 字符串都是一个独立的 token ,每一个token都会被增量处理(可以理解为一个一个地往上增加,类似于垒砖),这就是“增量模式”的含义。比如:
{"name" : "Morty"
}
Token 1 = "{"
Token 2 = "name"
Token 3 = "Morty"
Token 4 = "}"
4、流式API的缺点:虽然流式API在性能上有所特长,但是通过第三点,也可以知道,每一个token都是增量处理的,也就是说,我们必须要小心翼翼地处理每个token,这可能会因为粗心导致丢掉必要的token (如 "}"、"]" 等),而且代码可能并不简洁,可读性也不一定好,因此,不到需要考虑性能的时候,一定不要使用这种方式。
示例程序
通过Jackson Streaming APIs,写入一个json文件——“user.json”,并读出。
@Testpublic void testJsonGenerator() throws IOException {JsonFactory factory = new JsonFactory();// -----------------JsonGenerator --------------------JsonGenerator gentor = factory.createGenerator(new File("user.json"), JsonEncoding.UTF8);gentor.writeStartObject(); // {gentor.writeStringField("name", "Tomson");gentor.writeNumberField("age", 23);gentor.writeFieldName("messages");gentor.writeStartArray(); // [gentor.writeString("msg1");gentor.writeString("msg2");gentor.writeString("msg3");gentor.writeEndArray(); // ]gentor.writeEndObject(); // }gentor.close();// ------------------JsonParser --------------------JsonParser parser = factory.createParser(new File("user.json"));while (parser.nextToken() != JsonToken.END_OBJECT) {String fieldName = parser.getCurrentName();if ("name".equals(fieldName)) {// current token is "name",move to next which is "name"'s value.parser.nextToken();System.out.println(parser.getText());// display "Tomson"}if ("age".equals(fieldName)) {parser.nextToken();System.out.println(parser.getIntValue());}if ("messages".equals(fieldName)) {parser.nextToken();// messages is array, loop until equals "]"while(parser.nextToken() != JsonToken.END_ARRAY) {System.out.println(parser.getText());}}}parser.close();}
user.json文件内容:
程序执行输出结果:
总结
Jackson Streaming APIs是一种高性能、增量式json读写工具,在需要特殊性能要求的时候才会用到。缺点是代码不简洁,易错性高,可读性较差,可以通过jackson data binding代替。
token的概念,每一个json字符串都要被视为token,包括表示对象的大括号以及表示数组的中括号。
操作结束需要关流——close()。