关键API
JsonGenerator虽然仅是抽象基类,但Jackson它建议我们使用JsonFactory工厂来创建其实例,并不需要使用者去关心其底层实现类,因此我们仅需要面向此抽象类编程即可,此为对使用者非常友好的设计。
对于JSON生成器来说,写方法自然是它的灵魂所在。众所周知,JSON属于K-V数据结构,因此针对于一个JSON来说,每一段都k额分为写key和写value两大阶段。
写JSON Key
JsonGenerator一共提供了3个方法用于写JSON的key:
@Test public void test2() throws IOException { JsonFactory factory = new JsonFactory(); try (JsonGenerator jsonGenerator = factory.createGenerator(System.out, JsonEncoding.UTF8)) { jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("zhName"); jsonGenerator.writeEndObject(); } }
运行程序,输出:
{"zhName"}
可以发现,key可以独立存在(无需value),但value是不能独立存在的哦,下面你会看到效果。而3个方法中的其它2个方法:
public abstract void writeFieldName(SerializableString name) throws IOException; public void writeFieldId(long id) throws IOException { writeFieldName(Long.toString(id)); }
这两个方法,你可以忘了吧,记住writeFieldName()就足够了。
总的来说,写JSON的key非常简单的,这得益于JSON的key有且仅可能是String类型,所以情况单一。下面继续了解较为复杂的写Value的情况。
写JSON Value
我们知道在Java中数据存在的形式(类型)非常之多,比如String、int、Reader、char[]…,而在JSON中值的类型只能是如下形式:
- 字符串(如{ "name":"YourBatman" })
- 数字(如{ "age":18 })
- 对象(JSON 对象)(如{ "person":{ "name":"YourBatman", "age":18}})
- 数组(如{"names":[ "YourBatman", "A哥" ]})
- 布尔(如{ "success":true })
- null(如:{ "name":null })
小贴士:像数组、对象等这些“高级”类型可以互相无限嵌套
很明显,Java中的数据类型和JSON中的值类型并不是一一对应的关系,那么这就需要JsonGenerator在写入时起到一个桥梁(适配)作用:
下面针对不同的Value类型分别作出API讲解,给出示例说明。在此之前,请先记住两个结论,会更有利于你理解示例:
- JSON的顺序,和你write的顺序保持一致
- 写任何类型的Value之前请记得先write写key,否则可能无效
字符串
可把Java中的String类型、Reader类型、char[]字符数组类型等等写为JSON的字符串形式。
@Test public void test3() throws IOException { JsonFactory factory = new JsonFactory(); try (JsonGenerator jsonGenerator = factory.createGenerator(System.out, JsonEncoding.UTF8)) { jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("zhName"); jsonGenerator.writeString("A哥"); jsonGenerator.writeFieldName("enName"); jsonGenerator.writeString("YourBatman"); jsonGenerator.writeEndObject(); } }
运行程序,输出:
{"zhName":"A哥","enName":"YourBatman"} • 1
数字
参考上例,不解释。
对象(JSON 对象)
@Test public void test4() throws IOException { JsonFactory factory = new JsonFactory(); try (JsonGenerator jsonGenerator = factory.createGenerator(System.out, JsonEncoding.UTF8)) { jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("zhName"); jsonGenerator.writeString("A哥"); // 写对象(记得先写key 否则无效) jsonGenerator.writeFieldName("person"); jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("enName"); jsonGenerator.writeString("YourBatman"); jsonGenerator.writeFieldName("age"); jsonGenerator.writeNumber(18); jsonGenerator.writeEndObject(); jsonGenerator.writeEndObject(); } }
运行程序,输出:
{"zhName":"A哥","person":{"enName":"YourBatman","age":18}}
对象属于一个比较特殊的value值类型,可以实现各种嵌套。也就是我们平时所说的JSON套JSON
数组
写数组和写对象有点类似,也会有先start再end的闭环思路。
如何向数组里写入Value值?我们知道JSON数组里可以装任何数据类型,因此往里写值的方法都可使用,形如这样:
@Test public void test5() throws IOException { JsonFactory factory = new JsonFactory(); try (JsonGenerator jsonGenerator = factory.createGenerator(System.out, JsonEncoding.UTF8)) { jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("zhName"); jsonGenerator.writeString("A哥"); // 写数组(记得先写key 否则无效) jsonGenerator.writeFieldName("objects"); jsonGenerator.writeStartArray(); // 1、写字符串 jsonGenerator.writeString("YourBatman"); // 2、写对象 jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("enName", "YourBatman"); jsonGenerator.writeEndObject(); // 3、写数字 jsonGenerator.writeNumber(18); jsonGenerator.writeEndArray(); jsonGenerator.writeEndObject(); } }
运行程序,输出:
{"zhName":"A哥","objects":["YourBatman",{"enName":"YourBatman"},18]}
理论上JSON数组里的每个元素可以是不同类型,但原则上请确保是同一类型哦
对于JSON数组类型,很多时候里面装载的是数字或者普通字符串类型,因此JsonGenerator也很暖心的为此提供了专用方法(可以调用该方法来一次性便捷的写入单个数组):
@Test public void test6() throws IOException { JsonFactory factory = new JsonFactory(); try (JsonGenerator jsonGenerator = factory.createGenerator(System.out, JsonEncoding.UTF8)) { jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("zhName"); jsonGenerator.writeString("A哥"); // 快捷写入数组(从第index = 2位开始,取3个) jsonGenerator.writeFieldName("values"); jsonGenerator.writeArray(new int[]{1, 2, 3, 4, 5, 6}, 2, 3); jsonGenerator.writeEndObject(); } }
运行程序,输出:
{"zhName":"A哥","values":[3,4,5]}