Java Jackson-jr 库使用介绍

news2024/10/5 15:35:15

介绍

Jackson-jr 是一个轻量级的Java JSON 处理库。这个库被设计用来替代 Jackson 的复杂性。对比 Jackson 的复杂 API,Jackson-jr 的启动速度更快,包大小更小。

虽然Jackson databind(如ObjectMapper)是通用数据绑定的良好选择,但它的占用空间(Jar包大小)和启动开销在某些领域可能存在问题:比如移动端,特别是对于轻量使用(读或写)。这种情况下,完整的Jackson API是让人接受不了的。

由于所有这些原因,Jackson 官方决定创建一个更简单、更小的库:Jackson-jr。它仍旧构建在 Streaming API 之上,但不依赖于 databind 和annotation。因此,它的大小(jar和运行时内存使用)要小得多,它的API非常紧凑,所以适合APP等移动端。

它仅仅只依赖了 jackson-core 模块,所以体积上控制得非常的好。Jackson 单单三大核心模块大小合计1700KB左右(320 + 70 + 1370)。而Jackson-jr的体积控制在了95KB(就算加上core模块的320也不到500KB)。

针对实际开发的情况,很多时候我们只需要对 JSON 数据进行读取和写入,至于一些过于复杂和强大的属性,我们可能也用不上,因此针对一些 JSON 数据使用场景比较单一的情况,Jackson-jr 就显得更有优势了。

所以,Jackson-jr 的主要情况就是在针对 JSON 格式的读写上面,如果你只需要简单的读和些,Jackson-jr 通常是你的一个选择。

在本文中,我们对 Jackson-jr 的简单使用进行一些说明和示例。

开始使用 Jackson-jr

Jackson-jr 提供的是轻量和高效的 JSON 处理模块。所以 Jackson-jr 针对 JSON 数据结构只提供了简单的数据读取和写入功能。

当然 Jackson-jr 是可以处理对象和数组的。

在开始使用 Jackson-jr 之前,我们需要把需要的包添加到 Maven 项目的 pom 文件中。

当前的可以使用的最新版本为:2.17.0

<dependency>
    <groupId>com.fasterxml.jackson.jr</groupId>
    <artifactId>jackson-jr-all</artifactId>
    <version>2.17.0</version>
</dependency>

XML

针对 Gradle 可以使用不同的表达方式,唯一需要注意一点的就是版本号。

处理 JSON 对象

尽管我们是使用 Jackson-jr 来处理 JSON 字符串,和 Jackson 一样,字符串也会被处理成为 JSON 对象:每一个 JSON 实例是不可变(immutable )的,同时也是线程安全的。

正是因为有上面的特性,我们可以在多线程程序,单例模式,Spring Bean 中安全的使用创建的 JSON 对象。

创建 JSON 对象和数组

针对创建的 JSON 对象,我们可以使用类似 LinkedHashMap 来创建对象,对于数组,我们就可以用我们常用的 ArrayList。

因为 JSON 对象使用的是 LinkedHashMap,所以我们可以利用 Map 的特性,使用  LinkedHashMap.put() 方法来 Push 数据到 Map 中。

    @Test
    public void createJsonStringTest() throws IOException {
        System.out.println(JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
                .asString(new LinkedHashMap<String, Object>() {{
                    put("name", "John Doe");
                    put("age", 30);
                }}));
    }

Java

Jackson-jr Composer

Jackson-jr 同时还提供了 Composer 的这个创建方法,这个创建方法更加直接。

你可以按照你的想法直接进行定义和输出,在这之前,我们通常需要定义一个对象,然后对对象进行完成数据后再输出,对于一些简单的 JSON 格式。我们可以不用定义对象了,而是直接使用。

    public static String jsonComposer() throws IOException {
        return JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
          .composeString()
          .startObject()
          .startArrayField("objectArray")
          .startObject()
          .put("name", "name1")
          .put("age", 11)
          .end()
          .startObject()
          .put("name", "name2")
          .put("age", 12)
          .end()
          .end()
          .startArrayField("array")
          .add(1)
          .add(2)
          .add(3)
          .end()
          .startObjectField("object")
          .put("name", "name3")
          .put("age", 13)
          .end()
          .put("last", true)
          .end()
          .finish();
    }

Java

运行上面的程序后,程序将会输出:

{
  "objectArray" : [ {
    "name" : "name1",
    "age" : 11
  }, {
    "name" : "name2",
    "age" : 12
  } ],
  "array" : [ 1, 2, 3 ],
  "object" : {
    "name" : "name3",
    "age" : 13
  },
  "last" : true
}

Plain text

序列化和反序列化

Jackson-jr 可以让我们非常容易的把 Java 对象进行序列化,同时也能够非常容易的让我们从 JSON 字符串中读取为 Java 对象。

在对对象进行读写的时候,我们也可以对读写的属性进行定义,例如对输出的文本进行格式化或者使用自定义的日期属性进行输出,然后再从 Java 对象中写入到 String 字符串。

Jackson-jr 同时也能够支持复杂的数据结构,例如对象嵌套和数组等。通过对我们对象的关联关系的定义,我们可以让 JSON 字符串在进行反序列化序列化的时候完成对象映射,对于 Java 到 String 字符串的输出,其实也是一样。

// Serialization
String json = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
  .asString(person);

// Deserialization
json = "{\"name\":\"John Doe\",\"age\":30}";
Person person1 = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
  .beanFrom(Person.class, json);

Java

Jackson-jr 自定义选项

Jackson-jr 同时也支持大部分的注解(annotations)例如: @JsonProperty 这个和你日常使用的 Jackson 处理包是一样的。

你可以通过对对象注解的定义来控制序列化和反序列化的过程和数据。

对于可以支持的注解,可以范围 Jackson-jr 官方 GitHub 页面中有关的说明,这里我们就不一一列出,如果你用的是 Jackson 来处理序列化和反序列化的话,通常这些常用的注解应该还是比较熟悉的。

对于我们使用的序列化和反序列化输出来说,我们可以自定义输出,空对象如何输出等情况,这个和 Jackson 使用的方法是一致的。

JSON jsonMapper = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
  .with(JSON.Feature.WRITE_NULL_PROPERTIES)
  .with(JSON.Feature.FAIL_ON_DUPLICATE_MAP_KEYS);
String json = jsonMapper.asString(person);

Java

Jackson-jr 也允许我们创建自定义的序列化和反序列化来处理特定的数据类型和复杂的序列化方法。

通过对接口的实现, ValueWriter 和提供的继承的类, ValueReader 和 ReadWriterProvider,我们可以自定义和序列化和反序列化的方式。

Jackson-jr 现在还不能支持  java.time.*,但是我们还是可以添加自定义的序列化和反序列化,如下面我们使用的代码:

public class CustomDateSerializer implements ValueWriter {
    @Override
    public void writeValue (JSONWriter jsonWriter, JsonGenerator jsonGenerator, Object o) throws IOException {
        jsonGenerator.writeString(o.toString());
    }

    @Override
    public Class<?> valueType () {
        return LocalDate.class;
    }
}

Java

public class CustomDateDeserializer extends ValueReader {
    private final static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MMM-dd");

    public CustomDateDeserializer () {
        super(LocalDate.class);
    }

    @Override
    public Object read (JSONReader jsonReader, JsonParser jsonParser) throws IOException {
        return LocalDate.parse(jsonParser.getText(), dtf);
    }
}

Java

当我们把我们自定义的代码注册到 JSON 处理对象后,我们就可以使用了 LocalDate 对象。

public class MyHandlerProvider extends ReaderWriterProvider {

    @Override
    public ValueWriter findValueWriter (JSONWriter writeContext, Class<?> type) {
        if (type == LocalDate.class) {
            return new CustomDateSerializer();
        }
        return null;
    }

    @Override
    public ValueReader findValueReader (JSONReader readContext, Class<?> type) {
        if (type.equals(LocalDate.class)) {
            return new CustomDateDeserializer();
        }
        return null;
    }
}

Java

上面和下面的这些代码显示了如何我们如何使用自定义的序列化和反序列化方法。

Person person = new Person("John Doe", 30, LocalDate.now());

JSON jsonMapper = JSON.builder().register(new JacksonJrExtension() {
    @Override
    protected void register (ExtensionContext extensionContext) {
        extensionContext.insertProvider(new MyHandlerProvider());
    }   
}).build().with(JSON.Feature.PRETTY_PRINT_OUTPUT);

String json = jsonMapper.asString(person);
Person deserializedPerson = jsonMapper.beanFrom(Person.class, json);

Java

Jackson-jr 对比 Jackson

关于Jackson-jr 对比 Jackson 的内容,有人在做了一张下面的图。

简单点来说就 Jackson-jr 是Jackson 的轻量级应用,因为我们在很多时候都用不到 Jackson 的很多复杂功能。

对很多应用来说,我们可能只需要使用简单的 JSON 读写即可。

如我们用不到什么复杂的功能,并且使用了 Jackson-jr 能够满足你的项目使用的话,就直接使用 Jackson-jr 即可。

如发现 Jackson-jr 没有办法满足你的所有需求的时候,可以再切换到传统的 Jackson 包。

结论

Jackson-jr 提供了相对 Jackson 来说更加轻量的 JSON 数据处理模块。

对于很多只需要简单读写功能的 JSON 应用来说,就可以直接进行使用,对于服务器的应用,可能这个功能的削减对你的影响不大。

对大部分程序员来说,只需要了解 Jackson-jr 提供了一个轻量的兼容 JSON 大部分功能的解决方案即可。


Java Jackson-jr 库使用介绍 - Java - iSharkFly

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1641034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis---------分布式锁Redisson

概述 Redisson入门 第一步&#xff1a;引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version></dependency> 第二步&#xff1a;配置文件 import org.redisson…

django搭建一个AI博客进行YouTube视频自动生成文字博客

文章目录 一、生成Django框架二、项目代码&#xff08;前端&#xff09;1、编写前端代码&#xff08;正文界面&#xff09;1.1、生产html框架1.2、添加live preview扩展1.3、更改title元素中文本1.4、添加CDN&#xff08;CSS&#xff09;样式链接1.5、nav标签1.6、在body标签中…

全面了解俄罗斯的VK开户和Yandex投放及内容运营

俄罗斯的VKontakte&#xff08;简称VK&#xff09;和Yandex是两个重要的在线平台&#xff0c;对于希望在俄罗斯市场进行推广的企业来说&#xff0c;了解如何在这些平台上开户和投放广告以及内容运营是非常关键的。 俄罗斯vk广告如何开户&#xff1f; 通过上海上弦进行俄罗斯V…

ASP.NET网络在线考试系统

摘 要 随着计算机技术的发展和互联网时代的到来&#xff0c;人们已经进入了信息时代&#xff0c;也有人称为数字化时代。数在数字化的网络环境下&#xff0c;学生希望得到个性化的满足&#xff0c;根据自己的情况进行学习&#xff0c;同时也希望能够得到科学的评价&#xff0c…

(4)步态识别论文研读——增强时空显著性的跨视图步态识别

Enhanced Spatial-Temporal Salience for Cross-View Gait Recognition Enhanced Spatial-Temporal Salience for Cross-View Gait Recognition | IEEE Journals & Magazine | IEEE Xplore 摘要:步态识别可以单独或与其他生物特征相结合&#xff0c;用于个人识别和再识别…

242 基于matlab的3D路径规划

基于matlab的3D路径规划&#xff0c;蚁群算法&#xff08;ACO&#xff09;和天牛须&#xff08;BAS&#xff09;以及两种结合的三种优化方式&#xff0c;对3D路径规划的最短路径进行寻优。程序已调通&#xff0c;可直接运行。 242 3D路径规划 蚁群算法和天牛须 - 小红书 (xiaoh…

Redis---------实现更改数据业务,包括缓存更新,缓存穿透雪崩击穿的处理

三种更新策略 内存淘汰是Redis内存的自动操作&#xff0c;当内存快满了就会触发内存淘汰。超时剔除则是在存储Redis时加上其有限期(expire)&#xff0c;有限期一过就会自动删除掉。而主动更新则是自己编写代码去保持更新&#xff0c;所以接下来研究主动更新策略。 主动更新策略…

docker系列9:容器卷挂载(下)

传送门 docker系列1&#xff1a;docker安装 docker系列2&#xff1a;阿里云镜像加速器 docker系列3&#xff1a;docker镜像基本命令 docker系列4&#xff1a;docker容器基本命令 docker系列5&#xff1a;docker安装nginx docker系列6&#xff1a;docker安装redis docker系…

基于yolov8的苹果腐败检测系统,系统既支持图像检测,也支持视频和摄像实时检测(pytorch框架)【python源码+UI界面+功能源码详解】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; 基于yolov8的苹果腐败检测系统&#xff0c;系统既支持图像检测&#xff0c;也支持视频和摄像实时检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov8的苹果腐败检测系统是在pytorc…

QT:label标签/进度条的使用

文章目录 设置不同格式的文本显示图片文本对齐/自动换行/缩进/边距LCDNumber倒计时 ProgressBar进度条 设置不同格式的文本 在文本格式中&#xff0c;存在富文本&#xff0c;makedown格式的文本&#xff0c;还有纯文本&#xff0c;下面就依据这三个进行举例 #include "w…

MySQL-SQL执行流程及原理

1、SQL执行流程 2、查询流程 查询缓存&#xff1a; MySQL服务器如果在查询缓存中存在该SQL语句&#xff0c;就直接将结果返回给客户端&#xff0c;没有就进入解析器解析阶段。&#xff08;MySQL 8.0 删除该功能&#xff09;解析器&#xff1a;在解析器中对SQL语句进行语法及语…

G1 - 生成对抗网络(GAN)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目录 理论知识生成器判别器基本原理 环境步骤环境设置数据准备模型设计模型训练模型效果展示 总结与心得体会 理论知识 生成对抗网络&#xff08;Generative …

Docker 加持的安卓手机:随身携带的知识库(一)

这篇文章聊聊&#xff0c;如何借助 Docker &#xff0c;尝试将一台五年前的手机&#xff0c;构建成一个随身携带的、本地化的知识库。 写在前面 本篇文章&#xff0c;我使用了一台去年从二手平台购入的五年前的手机&#xff0c;K20 Pro。 为了让它能够稳定持续的运行&#xf…

如何让 PDF 书签从杂乱无序整洁到明丽清新

1、拉取书签&#xff08;详细步骤看文末扩展阅读&#xff09; 原状态 —— 杂乱无序 自动整理后的状态 —— 错落有致&#xff0c;但摩肩接踵 2、开始整理 全选自动整理后的书签&#xff0c;剪切 访问中英混排排版优化 - 油条工具箱 https://utils.fun/cn-en 1 粘贴 → 2 …

SwiftUI 5.0(iOS 17.0,macOS 14.0+)新 Inspector 辅助视图之趣味漫谈

概览 在 SwiftUI 开发中,苹果为我们提供了多种辅助视图用来显示额外信息从而极大丰富了应用的表现力,比如:Alert、Sheet、ContextMenu 等等。 从 SwiftUI 5.0(iOS 17+)开始, 又增加了一种全新的辅助视图:Inspector。 在本篇博文中,您将学到如下内容: 概览1. Inspe…

自定义拦截器jwt登录校验接口模拟账号登录

五一闲在宿舍&#xff0c;本来想写一个自己的简易博客网站&#xff0c;发现vue基础太差&#xff0c;做不出来页面效果于是便放弃&#xff0c;但也没有完全放弃。于是我分析了一下简易博客的后端实现流程&#xff0c;除了最基本的crud以外&#xff0c;在自己目前的对接口的分析中…

MATLAB 微积分

MATLAB 微积分 MATLAB提供了多种方法来解决微分和积分问题&#xff0c;求解任意程度的微分方程式以及计算极限。最重要的是&#xff0c;您可以轻松求解复杂函数的图&#xff0c;并通过求解原始函数及其导数来检查图上的最大值&#xff0c;最小值和其他文具点。 本章将讨论微…

Linux专栏08:Linux基本指令之压缩解压缩指令

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Linux专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Linux基本指令之压缩解压缩指令 编号&#xff1a;08 文章目录 Linu…

在2-3-4树上实现连接与分裂操作的算法与实现

在2-3-4树上实现连接与分裂操作的算法与实现 引言1. 维护2-3-4树结点的高度属性伪代码示例 2. 实现连接操作伪代码示例 3. 证明简单路径p的划分性质4. 实现分裂操作伪代码示例 C代码示例结论 引言 2-3-4树是一种平衡搜索树&#xff0c;它保证了树的高度被有效控制&#xff0c;…

python实验一 简单的递归应用

实验一 实验题目 1、兔子繁殖问题(Fibonacci’s Rabbits)。一对兔子从出生后第三个月开始&#xff0c;每月生一对小兔子。小兔子到第三个月又开始生下一代小兔子。假若兔子只生不死&#xff0c;一月份抱来一对刚出生的小兔子&#xff0c;问一年中每个月各有多少只兔子。 &…