Jackson 2.x 系列【3】解析器 JsonParser

有道无术,术尚可求,有术无道,止于术。

本系列Jackson 版本 2.17.0

源码地址:https://gitee.com/pearl-organization/study-seata-demo

文章目录

    • 1. 前言
    • 2. 解析原理
    • 3. 案例演示
      • 3.1 创建 JsonParser
      • 3.2 解析
      • 3.3 读取
      • 3.4 测试

1. 前言

在上一篇文档中,我们使用JsonGenerator生成了一个JSON文件,接下来我们学习使用JsonParser进行解析。

2. 解析原理

JsonParser进行解析的大致流程如下:

  1. 从头开始扫描JSON字符串
  2. 依次识别每个JSON组成元素
  3. 解析到结束位置,关闭解析器

在这里插入图片描述
JSON格式是非常标准的,JsonParser会从头到尾识别每一个组成元素,比如识别到对象开始符号{时,会生成一个对应JsonToken令牌对象,其中包含了元素标识START_OBJECT

JsonToken对象是一个枚举类,用于判断解析元素的类型:

public enum JsonToken {// 当前无法返回NOT_AVAILABLE((String)null, -1),// 对象开始符号:{START_OBJECT("{", 1),// 对象结束符号:}END_OBJECT("}", 2),// 数组开始符号START_ARRAY("[", 3),// 数组结束符号END_ARRAY("]", 4),// 当时是属性名称FIELD_NAME((String)null, 5),// 嵌入对象VALUE_EMBEDDED_OBJECT((String)null, 12),// 字符串类型值VALUE_STRING((String)null, 6),// INT类型值VALUE_NUMBER_INT((String)null, 7),// FLOAT类型值VALUE_NUMBER_FLOAT((String)null, 8),// True 类型值VALUE_TRUE("true", 9),// False 类型值VALUE_FALSE("false", 10),// null 值VALUE_NULL("null", 11);
}

3. 案例演示

演示需求: 将之前生成的JSON文件反序列化为User对象。

3.1 创建 JsonParser

JsonParser是读取JSON内容API的基类,它有很多实现子类:
在这里插入图片描述
其实例也是由JsonFactory创建,JsonFactory提供了多种创建方法:

    public abstract JsonParser createParser(byte[] data) throws IOException;public abstract JsonParser createParser(byte[] data, int offset, int len) throws IOException;public abstract JsonParser createParser(char[] content) throws IOException;public abstract JsonParser createParser(char[] content, int offset, int len) throws IOException;public abstract JsonParser createParser(DataInput in) throws IOException;public abstract JsonParser createParser(File f) throws IOException;public abstract JsonParser createParser(InputStream in) throws IOException;public abstract JsonParser createParser(Reader r) throws IOException;public abstract JsonParser createParser(String content) throws IOException;public abstract JsonParser createParser(URL url) throws IOException;

这里我们直接通过文件对象创建:

        // 1. 创建 JsonParserJsonFactory jsonFactory = JsonFactory.builder().build();File file = new File("E:\\TD\\pearl\\study-jackson-demo\\jackson-core-demo\\src\\main\\java\\com\\pearl\\jacksoncore\\demo\\file\\user.json");JsonParser jsonParser = jsonFactory.createParser(file);

上面创建的JsonParser 实例类型是UTF8StreamJsonParser
在这里插入图片描述

3.2 解析

JsonParser提供了isClosed()方法判断是否关闭,nextToken()方法解析下一个元素,使用这两个方法循环解析JSON的所有元素:

        while (!jsonParser.isClosed()) {JsonToken jsonToken = jsonParser.nextToken();System.out.println("当前解析到的令牌类型:" + jsonToken);}

所有元素类型如下:

当前解析到的令牌类型:START_OBJECT
当前解析到的令牌类型:FIELD_NAME
当前解析到的令牌类型:VALUE_NUMBER_INT
当前解析到的令牌类型:FIELD_NAME
当前解析到的令牌类型:VALUE_STRING
当前解析到的令牌类型:FIELD_NAME
当前解析到的令牌类型:VALUE_NUMBER_INT
当前解析到的令牌类型:FIELD_NAME
当前解析到的令牌类型:START_OBJECT
当前解析到的令牌类型:FIELD_NAME
当前解析到的令牌类型:VALUE_NUMBER_INT

3.3 读取

JsonParser提供了多个将JSON解析为对象或树模型的方法:
在这里插入图片描述
查看readValueAs方法,可以看到实际是调用ObjectCodec对象的读取方法:

    public <T> T readValueAs(Class<T> valueType) throws IOException {return this._codec().readValue(this, valueType);}protected ObjectCodec _codec() {ObjectCodec c = this.getCodec();if (c == null) {throw new IllegalStateException("No ObjectCodec defined for parser, needed for deserialization");} else {return c;}}

ObjectCodec是一个抽象类,定义了JsonParserJsonGenerator用于序列化和反序列化POJO对象的正则表达式,其标准实现为jackson-databind模块中的ObjectMapper类。ObjectCodec是非常重要的一个类,JSONPOJO转换的规则和逻辑需要实现该抽象类。

ObjectCodec中可以看到定义了很多读写方法,同时它继承了TreeCodec抽象类,说明也具备读取为树模型的能力:

public abstract class ObjectCodec extends TreeCodec implements Versioned {public abstract Version version();public abstract <T> T readValue(JsonParser var1, Class<T> var2) throws IOException;public abstract <T> T readValue(JsonParser var1, TypeReference<T> var2) throws IOException;public abstract <T> T readValue(JsonParser var1, ResolvedType var2) throws IOException;public abstract <T> Iterator<T> readValues(JsonParser var1, Class<T> var2) throws IOException;public abstract <T> Iterator<T> readValues(JsonParser var1, TypeReference<T> var2) throws IOException;public abstract <T> Iterator<T> readValues(JsonParser var1, ResolvedType var2) throws IOException;public abstract void writeValue(JsonGenerator var1, Object var2) throws IOException;public abstract <T extends TreeNode> T readTree(JsonParser var1) throws IOException;public abstract void writeTree(JsonGenerator var1, TreeNode var2) throws IOException;public abstract TreeNode createObjectNode();public abstract TreeNode createArrayNode();public abstract JsonParser treeAsTokens(TreeNode var1);public abstract <T> T treeToValue(TreeNode var1, Class<T> var2) throws JsonProcessingException;/** @deprecated */@Deprecatedpublic JsonFactory getJsonFactory() {return this.getFactory();}public JsonFactory getFactory() {return this.getJsonFactory();}
}

我们自定义一个StudyObjectCodec,这里只实现readValue(JsonParser jsonParser, Class<T> aClass)方法,也只解析了User的几个属性,因为解析比生成复杂的多,这里只是简单演示:

public class StudyObjectCodec extends ObjectCodec {// 省略其他实现@Overridepublic <T> T readValue(JsonParser jsonParser, Class<T> aClass) throws IOException {// 1. 创建用户对象User user = new User();// 2. 循环解析每一个元素while (!jsonParser.isClosed()) {// 解析到下一个元素JsonToken jsonToken = jsonParser.nextToken();System.out.println("当前解析到的令牌类型:" + jsonToken);// 2.1 如果是属性名称类型if (JsonToken.FIELD_NAME.equals(jsonToken)) {String currentName = jsonParser.currentName(); // 获取属性名System.out.println("属性名称:" + currentName);if ("id".equals(currentName) ) {jsonParser.nextToken(); // 解析到下一个元素,即为属性对应的值Long userId = jsonParser.getLongValue();user.setId(userId);}if ("name".equals(currentName)) {jsonParser.nextToken();String userName = jsonParser.getValueAsString();user.setName(userName);}if ("age".equals(currentName)) {jsonParser.nextToken();int age = jsonParser.getIntValue();user.setAge(age);}}}// 3. 返回return (T) user;}

最后设置ObjectCodec,完整代码如下:

public class JsonParserDemo {public static void main(String[] args) throws IOException {// 1. 创建 JsonParserJsonFactory jsonFactory = JsonFactory.builder().build();File file = new File("E:\\TD\\pearl\\study-jackson-demo\\jackson-core-demo\\src\\main\\java\\com\\pearl\\jacksoncore\\demo\\file\\user.json");JsonParser jsonParser = jsonFactory.createParser(file);// 2. 反序列化 jsonParser.setCodec(new StudyObjectCodec());User user = jsonParser.readValueAs(User.class);System.out.println(user);}
}

3.4 测试

运行测试案例,查看控制台:

User{id=1701893746586685440, name='坤坤', age=18, org=null, roleList=null}

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

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

相关文章

水果软件FL Studio 21 for mac 21.2.3.3586破解版的最新版本2024介绍安装

音乐是人类最美好的语言&#xff0c;它能够跨越国界、文化和语言&#xff0c;将人们紧密地联系在一起。在当今数字化时代&#xff0c;音乐创作已经不再是专业人士的专利&#xff0c;越来越多的音乐爱好者开始尝试自己动手制作音乐。而FL Studio21中文版编曲软件正是这样一个为你…

Elasticsearch8搭建及Springboot中集成使用

1.搭建 1.1.下载地址 Elasticsearch&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch Kibana&#xff1a;https://www.elastic.co/cn/downloads/kibana 1.2.具体过程 下载安装包&#xff1a;访问上述链接&#xff0c;下载适合你操作系统的Elasticsearch和Ki…

PyTorch 深度学习(GPT 重译)(五)

十二、通过指标和增强改进训练 本章涵盖 定义和计算精确率、召回率以及真/假阳性/阴性 使用 F1 分数与其他质量指标 平衡和增强数据以减少过拟合 使用 TensorBoard 绘制质量指标图 上一章的结束让我们陷入了困境。虽然我们能够将深度学习项目的机制放置好&#xff0c;但实…

故障诊断 | 一文解决,GRNN广义回归神经网络的故障诊断(Matlab)

文章目录 效果一览文章概述专栏介绍模型描述源码设计参考资料效果一览 文章概述 故障诊断 | 一文解决,GRNN广义回归神经网络的故障诊断(Matlab) 专栏介绍

TinTin Web3 Bounty 挑战杯开启,Sui 向你发出挑战邀请

以下文章来源于TinTinLand &#xff0c;作者TinTinLand。 2024 年开年最火的是什么&#xff1f; 对 Web3 来说&#xff0c;Bounty 任务应该是普通人获得行业“一杯羹”的重要捷径&#xff01; 通过深入学习各类 Web3 技术&#xff0c;凭借实战锻炼开发创新项目&#xff0c;就…

【python】【多线程】巧用Python 实现多线程批量将 Word 文档转换为PDF格式

以下是使用 Python 实现多线程批量将 doc 文档转换为 PDF 格式的示例代码: import os import threading import win32com.client from time import sleepclass DocToPdfThread(threading.Thread):def __init__(self, doc_file, output_dir):threading.Thread.__init__(self)se…

#微信小程序:微信小程序常见的配置传旨

微信小程序 app.js 设置全局的基础数据 通过 let app getApp() 获取里面的数据 app.json 设置tab,注册页面的路由 app.wxss 公共的样式&#xff0c;引入iconfont project.config.json 项目配置文件&#xff0c;用的最多就是配置是否开启https校验 pages 包含一个个…

Linux CentOS 7.6安装mysql5.7.26详细保姆级教程

一、通过wget下载mysql安装包 1、下载 //进入home目录 cd /home //下载mysql压缩包 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz //解压 tar -xvf mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz //重命名文件夹 mv mys…

MongoDB系列之查询计划

概述 一个查询具体如何被执行的过程&#xff0c;称为查询计划。MongoDB采用自底向上的方式来构造查询计划&#xff0c;每一个查询计划&#xff08;query plan&#xff09;都会被分解为若干个有层次的阶段&#xff08;stage&#xff09;。整个查询计划最终会呈现出一颗多叉树。…

ReaLTaiizor开源.NET winform控件库学习使用

一、ReaLTaiizor项目介绍 1.1 介绍及地址 基于MIT license开源、免费、美观的.NET WinForm UI控件库&#xff1a;ReaLTaiizor ReaLTaiizor是一个开源免费的.NET WinForms控件库&#xff0c;它提供了广泛的组件和丰富的主题选项&#xff08;用户友好、注重设计&#xff09;&am…

提供数字免疫力:采取整体方法来优化您的网络

采用数字技术已成为许多美国企业的关键竞争优势&#xff0c;导致其在与新部署的云解决方案的安全连接方面的投资不断增加。然而&#xff0c;随着越来越多的关键应用程序迁移到云端&#xff0c;公司保护其敏感数据和资源变得更具挑战性&#xff0c;因为这些资产现在超出了内部防…

C#中Console.WriteLine()函数输出格式详解

格式项都采用如下形式&#xff1a; {index[,alignment][:formatString]} 其中"index"指索引占位符&#xff0c;这个肯定都知道&#xff1b; “,alignment"按字面意思显然是对齐方式,以”,"为标记&#xff1b; “:formatString"就是对输出格式的限…

js读取本地 excel文件、txt文件的内容

<input type"file" change"fileChange"> 1、txt文件 fileChange(event) {console.log(fileChange, event)const file event.target.files[0];const reader new FileReader();reader.readAsText(file);reader.onload function(e) {console.log(r…

基于SpringBoot的学生成绩管理系统

基于SpringBootVue的家教管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 系统功能结构展示 登录界面图 现今&#xff0c;越来越多的人乐于选择一项合适的管理方案&#xff0c;但是普通用户往往受到管理经验地限制&…

ES 常见面试题及答案

目录 es 写入数据流程 es 删除数据流程 es 读数据流程 es 部署的服务有哪些角色 es 的实现原理 es 和lucence 关系 如何提高写入效率 提高搜索效率 es doc value指的啥 分片指的啥&#xff0c;定义后可不可义再修改 深分页如何优化 对于聚合操作是如何优化的 元数据…

面试九 设计模式

单例模式通常被归类为创建型设计模式&#xff0c;因为它主要关注如何创建对象的实例&#xff0c;以及如何确保在整个应用程序生命周期中只有一个实例存在。 1.为什么日志模块和数据库连接池需要单例模式 使用单例模式来实现数据库连接池主要有以下几个原因&#xff1a; 全局唯…

[自研开源] MyData 数据集成之任务调度模式 v0.7

开源地址&#xff1a;gitee | github 详细介绍&#xff1a;MyData 基于 Web API 的数据集成平台 部署文档&#xff1a;用 Docker 部署 MyData 使用手册&#xff1a;MyData 使用手册 试用体验&#xff1a;http://demo.mydata.work 交流 Q 群&#xff1a;430089673 概述 本…

四、Elasticsearch 进阶

自定义目录 4.1 核心概念4.1.1 索引&#xff08;Index&#xff09;4.1.2 类型&#xff08;Type&#xff09;4.1.3 文档&#xff08;Document&#xff09;4.1.3 字段&#xff08;Field&#xff09;4.1.5 映射&#xff08;Mapping&#xff09;4.1.6 分片&#xff08;Shards&#…

富格林:正视安全平台阻挠亏损

富格林悉知&#xff0c;当前不少投资者都意识到一款正规的平台能够帮助我们阻挠亏损确保安全。因此不少投资者在选择都会参考一些排行榜。但是网上这方面的榜单眼花缭乱&#xff0c;新手投资者可能难以从中挑选到能够帮助我们阻挠亏损确保安全的平台。下面富格林将给大家提供一…

STL_list文档使用介绍与底层代码实现简介

文章目录 list介绍list的使用构造函数&#xff08;constructor&#xff09;迭代器list capacitylist modify&#xff08;修改&#xff09;其他接口函数list迭代器失效问题 list实现基础框架(节点类&#xff09;基础框架&#xff08;迭代器类&#xff09;基础框架&#xff08;链…