5. JsonFactory工厂而已,还蛮有料,这是我没想到的(下)

简介: 5. JsonFactory工厂而已,还蛮有料,这是我没想到的(下)

运行程序,抛出异常。证明特征开启成功,符合预期。


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方式构建实例的。

image.png


文件内容为:

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工厂为核心,讲解了它是如何创建、定制读/写实例的。对于自己的实例的创建共有三种方式:


  1. 直接new实例
  2. 使用JsonFactoryBuilder构建(需要2.10或以上版本)
  3. SPI方式创建实例


其中方式2是被推荐的,如果你的版本较低,就老老实实使用方式1呗。至于方式3嘛,玩玩就行,别当真。


至此,jackson-core的三大核心内容:JsonGenerator、JsonParser、JsonFactory全部介绍完了,它们是jackson 其它所有模块 的基石,需要掌握扎实喽。


下篇文章更有意思,会分析Jackson里Feature机制的设计,使用补码、掩码来实现是高效的体现,同时设计上也非常优美,下文见。

相关文章
火爆Boss直聘的百页SpringBoot原理实战+面试题助你狂拿千份offer
近期,有个小伙伴出去面试老找不到工作,在面试的过程中问到了好多知识点都不会,都是一知半解,啪啪被打脸,还是工作3年开发的程序员。 结果,经过询问,才知道做了三年的开发,天天都是CRUD,按部就班,从来没有想过去提升自己的技术,也不愿意跳槽,就一直温水煮青蛙,不成想被裁掉了。 被裁掉之后,他就想着去面试一下吧!反正有三年工作经验在手,怕什么?于是,四处碰壁,加上java比较卷,大环境又不好,公司招聘要求又高,又到了年底,就迟迟找不到工作。
|
JSON 安全 Java
5. JsonFactory工厂而已,还蛮有料,这是我没想到的
一件事情本身的复杂度并不会凭空消失,而是从一个地方转移到另外一个地方
1150 0
5. JsonFactory工厂而已,还蛮有料,这是我没想到的
|
设计模式 缓存 JavaScript
设计模式(二)—— 创建型模式|牛气冲天新年征文
设计模式(二)—— 创建型模式|牛气冲天新年征文
96 0
|
设计模式 算法 架构师
YYDS!由浅入深学习阿里JDK源码,已在阿里内部疯拿3个金奖
大家好,又是我你们不知道喜不喜爱的架构师之道,今天呢,我想和大家聊一聊JDK源码的问题: * **为什么要看JDK源码** * **JDK源码的阅读顺序** * **JDK源码的最佳学习方法**
158 0
YYDS!由浅入深学习阿里JDK源码,已在阿里内部疯拿3个金奖
|
设计模式 JSON 安全
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(上)
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(上)
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(上)
|
存储 JSON JavaScript
听说你情人节没人陪,这不我来给你介绍对象啦
听说你情人节没人陪,这不我来给你介绍对象啦
244 0
听说你情人节没人陪,这不我来给你介绍对象啦
|
缓存 Java 数据处理
科大爱情故事之线程池工厂打工记
科大爱情故事之线程池工厂打工记
130 0
|
存储 数据采集 运维
给工厂做开发,竟然喝着咖啡听“交响”?
给工厂做开发,竟然喝着咖啡听“交响”?云上不只有存储和计算,还有知识和经验。云计算提供的不只是一台一台的服务器,它提供给你的是丰富的知识和经验,你不光可以学习和使用,也可以基于这些知识经验去发展出属于你的新的知识和经验。”
756 0
给工厂做开发,竟然喝着咖啡听“交响”?
|
存储 JSON 缓存
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(中)
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(中)
|
程序员 区块链 新零售
干了这碗鸡汤:从理发店小弟到阿里P10技术大牛
1、引言 MIT TR 35(MIT Technology Review 35 Innovators Under 35)——“全球 35 位 35 岁以下科技创新青年”榜单,是全球最权威的青年科技创新人才榜单之一。
2752 0