2. 妈呀,Jackson原来是这样写JSON的(上)

简介: 2. 妈呀,Jackson原来是这样写JSON的(上)

前言


各位好,我是A哥(YourBatman)。上篇文章 整体介绍了世界上最好的JSON库 – Jackson,对它有了整体了解:知晓了它是个生态,其它的仅是个JSON库而已。


有人说Jackson小众?那么请先看看上篇文章吧。学Jackson性价比特别高,因为它使用广泛、会的人少,因此在团队内如果你能精通,附加价值的效应就会非常明显了…


我挠头想了想,本系列来不了虚的,只能肝。本系列教程不仅仅教授基本使用,目标是搞完后能够解决日常99.99%的问题,毕竟每个小团队都最好能有某些方面的小专家,毕竟大家都不乏遇见过一个技术问题卡一天的情况。只有从底层把握,方能游刃有余



命名为core的模块一般都不简单,jackson-core自然也不例外。它是三大核心模块之一,并且是核心中的核心,提供了对JSON数据的完整支持(包括各种读、写)。它是三者中最强大的模块,具有最低的开销和最快的读/写操作。


此模块提供了最具底层的Streaming JSON解析器/生成器,这组流式API属于Low-Level API,具有非常显著的特点:


  • 开销小,损耗小,性能极高
  • 因为是Low-Level API,所以灵活度极高
  • 又因为是Low-Level API,所以易错性高,可读性差


jackson-core模块提供了两种处理JSON的方式(纵缆整个Jackson共三种):


  1. 流式API:读取并将JSON内容写入作为离散事件 -> JsonParser读取数据,而JsonGenerator负责写入数据
  2. 树模型:JSON文件在内存里以树形式表示。此种方式也很灵活,它类似于XML的DOM解析,层层嵌套的


作为“底层”技术,应用级开发中确实接触不多。为了引起你的重视,提前预告一下:Spring MVC对JSON消息的转换器AbstractJackson2HttpMessageConverter它就用到了底层流式API -> JsonGenerator写数据。想不想拿下Spring呢?我想你的答案应该是Yes吧~


相信做难事必有所得,你我他都会用的技术、都能解决的问题,那绝成不了你的核心竞争力,自然在团队内就难成发光体。


版本约定


原则:均选当前最新版本(忽略小版本)


  • Jackson版本:2.11.0
  • Spring Framework版本:5.2.6.RELEASE
  • Spring Boot版本:2.3.0.RELEASE
  • 内置的Jackson和Spring版本均和👆保持一致,避免了版本交叉


说明:类似2.11.0和2.11.x这种小版本号的差异,你权可认为没有区别


工程结构


鉴于是首次展示工程示例代码,将基本结构展示如下:


image.png


image.png


全部源码地址在本系列的最后一篇文章中会全部公示出来


正文


Jackson提供了一种对性能有极致要求的方式:流式API。它用于对性能有极致要求的场景,这个时候就可以使用此种方式来对JSON进行读写。


概念解释:流式、增量模式、JsonToken


  • 流式(Streaming):此概念和Java8中的Stream流是不同的。这里指的是IO流,因此具有最低的开销和最快的读/写操作(记得关流哦)
  • 增量模式(incremental mode):它表示每个部分一个一个地往上增加,类似于垒砖。使用此流式API读写JSON的方式使用的均是增量模式
  • JsonToken:每一部分都是一个独立的Token(有不同类型的Token),最终被“拼凑”起来就是一个JSON。这是流式API里很重要的一个抽象概念。


关于增量模式和Token概念,在Spirng的SpEL表达式中也有同样的概念,这在Spring相关专栏里你将会再次体会到

image.png



本文将看看它是如何写JSON数据的,也就是JsonGenerator。


JsonGenerator使用Demo


JsonGenerator定义用于编写JSON内容的公共API的基类(抽象类)。实例使用的工厂方法创建,也就是JsonFactory。


小贴士:纵观整个Jackson,它更多的是使用抽象类而非接口,这是它的一大“特色”。因此你熟悉的面向接口编程,到这都要转变为面向抽象类编程喽。


话不多说,先来一个Demo感受一把:


@Test
public void test1() throws IOException {
    JsonFactory factory = new JsonFactory();
    // 本处只需演示,向控制台写(当然你可以向文件等任意地方写都是可以的)
    JsonGenerator jsonGenerator = factory.createGenerator(System.out, JsonEncoding.UTF8);
    try {
        jsonGenerator.writeStartObject(); //开始写,也就是这个符号 {
        jsonGenerator.writeStringField("name", "YourBatman");
        jsonGenerator.writeNumberField("age", 18);
        jsonGenerator.writeEndObject(); //结束写,也就是这个符号 }
    } finally {
        jsonGenerator.close();
    }
}


因为JsonGenerator实现了AutoCloseable接口,因此可以使用try-with-resources优雅关闭资源(这也是推荐的使用方式),代码改造如下:


@Test
public void test1() throws IOException {
    JsonFactory factory = new JsonFactory();
    // 本处只需演示,向控制台写(当然你可以向文件等任意地方写都是可以的)
    try (JsonGenerator jsonGenerator = factory.createGenerator(System.out, JsonEncoding.UTF8)) {
        jsonGenerator.writeStartObject(); //开始写,也就是这个符号 {
        jsonGenerator.writeStringField("name", "YourBatman");
        jsonGenerator.writeNumberField("age", 18);
        jsonGenerator.writeEndObject(); //结束写,也就是这个符号 }
    }
}


运行程序,控制台输出:

{"name":"YourBatman","age":18}

这是最简使用示例,这也就是所谓的序列化底层实现,从示例中对增量模式能够有所感受吧。


纯手动档有木有,灵活性和性能极高,但易出错。这就像头文字D的赛车一样,先要速度、高性能、灵活性,那必须上手动档


JsonGenerator详细介绍


JsonGenerator是个抽象类,它的继承体系如下:


image.png


  • WriterBasedJsonGenerator:基于java.io.Writer处理字符编码(话外音:使用Writer输出JSON)
  • 因为UTF-8编码基本标准化了,因此Jackson内部也提供了SegmentedStringWriter/UTF8Writer来简化操作
  • UTF8JsonGenerator:基于OutputStream + UTF-8处理字符编码(话外音:明确指定了使用UTF-8编码把字节变为字符)


默认情况下(不指定编码),Jackson默认会使用UTF-8进行编码,也就是说会使用UTF8JsonGenerator作为实际的JSON生成器实现类,具体逻辑将在讲述JsonFactory章节中有所体现,敬请关注。


值得注意的是,抽象基类JsonGenerator它只负责JSON的生成,至于把生成好的JSON写到哪里去它并不关心。比如示例中我给写到了控制台,当然你也可以写到文件、写到网络等等。


Spring MVC中的JSON消息转换器就是向HttpOutputMessage(网络输出流)里写JSON数据


相关文章
|
6月前
|
XML JSON 前端开发
Ajax技术【Ajax技术详解、 Ajax 的使用、Ajax请求、 JSON详解、JACKSON 的使用 】(一)-全面详解(学习总结---从入门到深化)
Ajax技术【Ajax技术详解、 Ajax 的使用、Ajax请求、 JSON详解、JACKSON 的使用 】(一)-全面详解(学习总结---从入门到深化)
155 1
|
1月前
|
JSON JavaScript Java
在Java中处理JSON数据:Jackson与Gson库比较
本文介绍了JSON数据交换格式及其在Java中的应用,重点探讨了两个强大的JSON处理库——Jackson和Gson。文章详细讲解了Jackson库的核心功能,包括数据绑定、流式API和树模型,并通过示例演示了如何使用Jackson进行JSON解析和生成。最后,作者分享了一些实用的代码片段和使用技巧,帮助读者更好地理解和应用这些工具。
在Java中处理JSON数据:Jackson与Gson库比较
|
3月前
|
JSON Java API
Jackson:SpringBoot中的JSON王者,优雅掌控数据之道
【8月更文挑战第29天】在Java的广阔生态中,SpringBoot以其“约定优于配置”的理念,极大地简化了企业级应用的开发流程。而在SpringBoot处理HTTP请求与响应的过程中,JSON数据的序列化和反序列化是不可或缺的一环。在众多JSON处理库中,Jackson凭借其高效、灵活和强大的特性,成为了SpringBoot中处理JSON数据的首选。今天,就让我们一起深入探讨Jackson如何在SpringBoot中优雅地控制JSON数据。
127 0
|
5月前
|
JSON fastjson 数据格式
使用jackson和fastjson实现list与json互转
使用jackson和fastjson实现list与json互转
|
6月前
|
JSON 安全 JavaScript
Java一分钟之-JSON处理:Gson与Jackson库
本文对比介绍了Java中常用的两个JSON库Gson和Jackson。Gson以其简洁易用和自动序列化/反序列化功能受到青睐,而Jackson则以优异性能和丰富功能(如字段忽略、日期格式化)著称。文中通过代码示例展示了两者的基本用法,并讨论了常见问题及解决策略,包括时间格式处理、循环引用和类型匹配。在实际应用中,应根据性能需求、安全性和版本兼容性选择合适的库,并遵循最佳实践。
192 0
|
6月前
|
JSON fastjson Java
Spring Boot Jackson 和Fast JSON 用哪个好啊 ?
【4月更文挑战第22天】
1042 1
|
6月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
132 0
|
XML JSON Java
Jackson 框架,轻易转换JSON
Jackson 框架,轻易转换JSON Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。 前面有介绍过json-lib这个框架,在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/21/2023805.html 相比json-lib框架,Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。
3025 0
|
29天前
|
数据采集 JSON 数据处理
抓取和分析JSON数据:使用Python构建数据处理管道
在大数据时代,电商网站如亚马逊、京东等成为数据采集的重要来源。本文介绍如何使用Python结合代理IP、多线程等技术,高效、隐秘地抓取并处理电商网站的JSON数据。通过爬虫代理服务,模拟真实用户行为,提升抓取效率和稳定性。示例代码展示了如何抓取亚马逊商品信息并进行解析。
抓取和分析JSON数据:使用Python构建数据处理管道