运行程序,抛出异常。证明特征开启成功,符合预期。
com.fasterxml.jackson.core.JsonParseException: Duplicate field 'age' at [Source: (String)"{"age":18, "age": 28 }"; line: 1, column: 17]
在使用JsonFactory定制化读/写实例的时需要特别注意:请务必确保在factory.createXXX()之前配置好对应的Feature特征,若在实例创建好之后再弄的话,对已经创建的实例无效。
小贴士:实例创建好后若你还想定制,可以使用实例自己的对应API操作
JsonFactoryBuilder
JsonFactory负责基类和实现类的双重任务,是比较重的,分离得也不彻底。同时,现在都2020年了,对于这种构建类工厂如果还不用Builder模式就现在太out了,书写起来也非常不便:
@Test public void test4() throws IOException { JsonFactory jsonFactory = new JsonFactory(); // jsonFactory自己的特征 jsonFactory.enable(JsonFactory.Feature.INTERN_FIELD_NAMES); jsonFactory.enable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES); jsonFactory.enable(JsonFactory.Feature.USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING); // JsonParser的特征 jsonFactory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES); jsonFactory.enable(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER); // JsonGenerator的特征 jsonFactory.enable(JsonGenerator.Feature.QUOTE_FIELD_NAMES); jsonFactory.enable(JsonGenerator.Feature.ESCAPE_NON_ASCII); // 创建读/写实例 // jsonFactory.createParser(...); // jsonFactory.createGenerator(...); }
功能实现上没毛病,但总显得不够优雅。同时上面也说了:定制化操作一定得在create创建动作之前执行,这全靠程序员自行控制。
Jackson在2.10版本新增了一个JsonFactoryBuilder构件类,让我们能够基于builder模式优雅的构建出一个JsonFactory实例。
小贴士:2.10版本是2019.09发布的
比如上面例子的代码使用JsonFactoryBuilder可重构为:
@Test public void test4() throws IOException { JsonFactory jsonFactory = new JsonFactoryBuilder() // jsonFactory自己的特征 .enable(INTERN_FIELD_NAMES) .enable(CANONICALIZE_FIELD_NAMES) .enable(USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING) // JsonParser的特征 .enable(ALLOW_SINGLE_QUOTES, ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER) // JsonGenerator的特征 .enable(QUOTE_FIELD_NAMES, ESCAPE_NON_ASCII) .build(); // 创建读/写实例 // jsonFactory.createParser(...); // jsonFactory.createGenerator(...); }
对比起来,使用Builder模式优雅太多了。
因为JsonFactory是线程安全的,因此一般情况下全局我们只需要一个JsonFactory实例即可,推荐使用JsonFactoryBuilder去完成你的构建。
小贴士:使用JsonFactoryBuilder确保你的Jackson版本至少是2.10版本哦~
SPI方式
从源码包里发现,JsonFactory是支持Java SPI方式构建实例的。
文件内容为:
com.fasterxml.jackson.core.JsonFactory
因此,我可以使用Java SPI的方式得到一个JsonFactory实例:
@Test public void test5() { ServiceLoader<JsonFactory> jsonFactories = ServiceLoader.load(JsonFactory.class); System.out.println(jsonFactories.iterator().next()); }
运行程序,妥妥的输出:
com.fasterxml.jackson.core.JsonFactory@4abdb505
这种方式,玩玩即可,在这里没实际用途。
总结
本文围绕JsonFactory工厂为核心,讲解了它是如何创建、定制读/写实例的。对于自己的实例的创建共有三种方式:
- 直接new实例
- 使用JsonFactoryBuilder构建(需要2.10或以上版本)
- SPI方式创建实例
其中方式2是被推荐的,如果你的版本较低,就老老实实使用方式1呗。至于方式3嘛,玩玩就行,别当真。
至此,jackson-core的三大核心内容:JsonGenerator、JsonParser、JsonFactory全部介绍完了,它们是jackson 其它所有模块 的基石,需要掌握扎实喽。
下篇文章更有意思,会分析Jackson里Feature机制的设计,使用补码、掩码来实现是高效的体现,同时设计上也非常优美,下文见。