java snack_Java 中 Snack3的使用

2023-11-17

网上看了一篇Java 中 Gson的使用,所以也跟着写篇Java 中 Snack3的使用

JSON 是一种文本形式的数据交换格式,从Ajax的时候开始流行,它比XML更轻量、比二进制容易阅读和编写;解析和生成的方式很多,Java中最常用的类库有:JSON-Java、Gson、Jackson、FastJson、Snack3等。

Snack3 基于jdk8,60kb大小,非常小巧。

org.noear

snack3

3.1.8

Snack3 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计。其下一切数据都以ONode表示,ONode也即 One node 之意,代表任何类型,也可以转换为任何类型。

强调文档树的操控和构建能力

做为中间媒体,方便不同格式互转

高性能Json path查询(兼容性和性能很赞)

支持序列化、反序列化

一、Snack3的基本用法

Snack3提供了几个快捷函数:

load(strOrObj), loadStr(str), loadObj(obj) 用于解析和加载;

stringify(obj), serialize(obj), deserialize(str,clz) 用于序列化和反序列化

(1)基本数据类型的解析

int i = ONode.load("100").getInt(); //100

double d = ONode.load("\"99.99\"").getDouble(); //99.99

boolean b = ONode.load("true").getBoolean(); // true

String str = ONode.load("String").getString(); // String

(2)基本数据类型的生成

String jsonNumber = ONode.load(100).toJson(); // 100

String jsonBoolean = ONode.load(false).toJson(); // false

String jsonString = ONode.load("String").toString(); //"String"

(3)POJO类的生成与解析

public class User {

public String name;

public int age;

public String emailAddress;

}

生成JSON:

User user = new User("张三",24);

//输出: {"name":"张三","age":24}

String json = ONode.stringify(user); //JSON字符化

//输出: {"@type":"demo.User","name":"\u5F20\u4E09","age":24}

String json2 = ONode.serialize(user); //JSON序列化

解析并反序列化JSON:

String json = "{name:'张三',age:24}";

User user = ONode.deserialize(json, User.class);//JSON反序列化

二、序列化事项补充说明

从上面示例可以看出json的字段和值是的名称和类型是一一对应的,Snack3不支持直接改名称,但可以通过transient关键字进行排序,例:

public class User {

public String name;

public int age;

public String emailAddress;

public transient Date date;

}

或者,加载后再重改名称,例:

User user = new User("name", 12, "xxx@mail.cn");

//输出: {"name":"name","age":12,"email":"xxx@mail.cn"}

ONode.load(user).rename("emailAddress","email").toJson();

//o.rename(key,newKey); //重命名子节点,并返回自己

Snack3在序列化和反序列化时需要使用反射,且只对字段进行序列化(不管属性)。

特性总结:

只对字段进行序列化(包括私有)

使用transient 对字段排序

加载后可进行重命名字段

三、Snack3中使用泛型

例如:JSON字符串数组:["Android","Java","PHP"]

当要通过Snack3解析这个json时,一般有三种方式:使用ONode,使用数组,使用List;而List对于增删都是比较方便的,所以实际使用是还是List比较多

数组比较简单:

String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";

String[] strings = ONode.deserialize(jsonArray,String[].class);

对于List将上面的代码中的 String[].class 直接改为 List.class 是不行的,对于Java来说List 和List 这俩个的字节码文件只一个那就是List.class,这是Java泛型使用时要注意的问题 泛型擦除。

为了解决的上面的问题,Snack3提供了2种方式来实现对泛型的支持,所以将以上的数据解析为List时需要这样写:

String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";

ONode ary0 = ONode.load(jsonArray);

List ary1 = ONode.deserialize(jsonArray,(new ArrayList(){}).getClass());

List ary2 = ONode.deserialize(jsonArray,(new TypeRef>(){}).getClass());

//(new ArrayList(){}).getClass() //方式1,通过临时类形(最终都是产生Class)

//(new TypeRef>(){}).getClass() //方式2,通过TypeRef(最终都是产生Class)

泛型的引入还可以减少无关的代码:

{"code":"0","message":"success","data":{}}

{"code":"0","message":"success","data":[]}

像上面这段代码,code只使用一次,message则几乎不用;我们真正需要的data所包含的数据,但它可能对象也可能是数组。如果Snack3不支持泛型或不知道Snack3支持泛型的同学一定会这么定义POJO:

public class UserResponse {

public int code;

public String message;

public User data;

}

当设计其它接口的时候又重新定义一个XxxResponse将data的类型改成Xxx,很明显code,和message被重复定义了多次,会产大量的POJO。。。通过泛型可以将code和message字段抽取到一个Result的类中,这样只需要编写data字段所对应的POJO即可:

public class Result {

public int code;

public String message;

public T data;

}

四、Snack3的序列化与反序列化

(1)自动方式

Snack3提供了serialize(obj)和deserialize(str,clz) 前者实现序列化,后者实现了反序列化。

ONode.serialize(obj); //序列化

ONode.deserialize(str,clz); //反序列化

(2)手动方式:

手动的方式使用load(obj),toObject(clz),toJson() 来手动实现序列化和反序列化:

String json = "{\"name\":\"张三\",\"age\":\"24\"}";

//反序列化

User user = ONode.load(json,Constants.serialize()).toObject(User.class);

//序列化

ONode.load(user,Constants.serialize()).toJson();

自动方式最终都是通过load(obj),toObject(clz),toJson() 进行操作。

内部代码:

/**

* 序列化为 string(由序列化器决定格式)

*

* @param source java object

* @throws Exception

*/

public static String serialize(Object source) {

//加载java object,须指定Fromer

return load(source, Constants.serialize(), DEFAULTS.DEF_OBJECT_FROMER).toJson();

}

/**

* 反序列化为 java object(由返序列化器决定格式)

*

* @param source string

* @throws Exception

*/

public static T deserialize(String source, Class> clz) {

//加载String,不需指定Fromer

return load(source, Constants.serialize(), null).toObject(clz);

}

五、使用Snack3导出null值、格式化输出、日期时间

一般情况下ONode类提供的 API已经能满足大部分的使用场景,但有时需要更多特殊、强大的功能时,这时候就引入一个新的类 Constants。

Constants从名字上看它是一个提供配置的类,要想改变ONode默认的设置必须使用该类进行配置。用法:

Constants.of(..) //全新定义一份配置

Constants.def().add(..).sub(..) //在默认配置基础上,添加或减少特性

Constants.serialize().add(..).sub(..) //在序列化配置基础上,添加或减少特性

(1)Snack3在默认情况下是不动导出值null的键的,如:

User user = new User("张三", 24);

System.out.println(ONode.stringify(user)); //{"name":"张三","age":24}

Constants cfg = Constants.def().add(Feature.SerializeNulls); //导出null

System.out.println(ONode.load(user, cfg).toJson()); //{"name":"张三","age":24,"emailAddress":null}

(2)格式化输出、日期时间及其它:

Date date = new Date();

Constants cfg = Constants.of(Feature.WriteDateUseFormat) //使用格式化特性

.build(c-> c.date_format = new SimpleDateFormat("yyyy-MM-dd",c.locale)); //设置格式符(默认为:"yyyy-MM-dd'T'HH:mm:ss")

System.out.println(ONode.load(date, cfg).toJson()); //2019-12-06

六、使用Snack3进行JSONPath查询

在网上找了一份经典的JSON样本:

{

"store": {

"bicycle": {

"color": "red",

"price": 19.95

},

"book": [

{

"author": "刘慈欣",

"price": 8.95,

"category": "科幻",

"title": "三体"

},

{

"author": "itguang",

"price": 12.99,

"category": "编程语言",

"title": "go语言实战"

}

]

}

}

Snack3可以提供高速的JSONPath查询,JSONPath更给日常的查询节省了大量代码:

ONode o = ONode.load(jsonStr);

//得到所有的书

ONode books = o.select("$.store.book");

System.out.println("books=::" + books);

//得到所有的书名

ONode titles = o.select("$.store.book.title");

System.out.println("titles=::" + titles);

//第一本书title

ONode title = o.select("$.store.book[0].title");

System.out.println("title=::" + title);

//price大于10元的book

ONode list = o.select("$.store.book[?(price > 10)]");

System.out.println("price大于10元的book=::" + list);

//price大于10元的title

ONode list2 = o.select("$.store.book[?(price > 10)].title");

System.out.println("price大于10元的title=::" + list2);

//category(类别)为科幻的book

ONode list3 = o.select("$.store.book[?(category == '科幻')]");

System.out.println("category(类别)为科幻的book=::" + list3);

//bicycle的所有属性值

ONode values = o.select("$.store.bicycle.*");

System.out.println("bicycle的所有属性值=::" + values);

//bicycle的color和price属性值

ONode read = o.select("$.store.bicycle['color','price']");

System.out.println("bicycle的color和price属性值=::" + read);

(1)支持的JSONPath语法

字符串使用单引号,例:['name']

过滤操作用空隔号隔开,例:[?(@.type == 1)]

支持操作

说明

$

表示根元素

@

当前节点(做为过滤表达式的谓词使用)

*

通用配配符,可以表示一个名字或数字。

..

深层扫描。 可以理解为递归搜索。

.

表示一个子节点

['' (, '')]

表示一个或多个子节点

[ (, )]

表示一个或多个数组下标(负号为倒数)

[start:end]

数组片段,区间为[start,end),不包含end(负号为倒数)

[?()]

过滤表达式。 表达式结果必须是一个布尔值。

支持过滤操作符

说明

==

left等于right(注意1不等于'1')

!=

不等于

<

小于

<=

小于等于

>

大于

>=

大于等于

=~

匹配正则表达式[?(@.name =~ /foo.*?/i)]

in

左边存在于右边 [?(@.size in ['S', 'M'])]

nin

左边不存在于右边

支持尾部函数

说明

min()

计算数字数组的最小值

max()

计算数字数组的最大值

avg()

计算数字数组的平均值

sum()

计算数字数组的汇总值(新加的)

像这两种写法的语义是差不多:

$.store.book[0].title //建议使用这种

$['store']['book'][0]['title']

(2)语法示例说明

JSONPath

说明

$

根对象

$[-1]

最后元素

$[:-2]

第0个至倒数第2个

$[1:]

第1个之后所有元素(0为首个)

$[1,2,3]

集合中1,2,3个元素(0为首个)

七、数据格式互转

Snack3是采用(Fromer)->(ONode)->(Toer)的架构。非常适合格式的转换,开发时只需要完成与ONode的对接即可:

(1)将Xml转为Ymal

String xml = "....";

XmlFromer xmlFromer = new XmlFromer();

YmalToer ymalToer = new YmalToer();

//加载xml,输出ymal

String ymal = ONode.load(xml,Constants.def(),xmlFromer).to(ymalToer);

(2)加载Xml,去掉手机号,转为java object

ONode tmp =ONode.load(xml,Constants.def(),xmlFromer);

//找到有手机号的,然后移除手机号

tmp.select("$..[?(@.mobile)]").forEach(n->n.remove("mobile"));

XxxModel m =tmp.toObject(XxxModel.class);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java snack_Java 中 Snack3的使用 的相关文章

  • Q-Learning与Deep Q-network

    1 价值迭代 价值迭代方法假设事先知道环境中的所有状态 可以对其进行迭代 并可以存储与他们关联的近似价值 对于状态价值步骤如下 对于动作价值步骤如下 存在的问题 获得优质状态转移动态的估计所需的样本数量 状态空间需要足够小 将问题限制在离散
  • 920. 最优乘车(BFS 流式输入)

    H城是一个旅游胜地 每年都有成千上万的人前来观光 为方便游客 巴士公司在各个旅游景点及宾馆 饭店等地都设置了巴士站并开通了一些单程巴士线路 每条单程巴士线路从某个巴士站出发 依次途经若干个巴士站 最终到达终点巴士站 一名旅客最近到H城旅游
  • 移远EC20模组MQTT连接阿里云平台

    一 实现原理 在开始操作前说一下MQTT的实现的原理 MQTT协议 Message Queuing Telemetry Transport 消息队列遥测传输 是IBM开发的一个即时通讯协议 是为大量计算能力有限 且工作在低带宽 不可靠的网络
  • 使用 gvm 来快速安装或者升级 golang 版本

    gvm 是 golang 的版本管理工具 有点类似于 python 的 pyenv 一 安装 gvm bash lt lt curl s S L https raw githubusercontent com moovweb gvm mas
  • 自然对数e的来历

    e是自然对数的底数 是一个无限不循环小数 其值是2 71828 是这样定义的 当n gt 时 1 1 n n的极限 注 x y表示x的y次方 随着n的增大 底数越来越接近1 而指数趋向无穷大 那结果到底是趋向于1还是无穷大呢 其实 是趋向于
  • win10与Linux虚拟机进行文件共享

    由于工作需要使用到linux虚拟机 为了实现win10与Linux虚拟机进行文件共享 分享教程如下 1 在windows系统中设置文件共享 设置过程参考我之前的文章 局域网内共享文件夹 2 虚拟机设置共享文件夹 1 设置 gt 共享文件夹
  • openGLAPI之glPolygonOffset

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 glPolygonOffset官方文档 二 翻译 前言 openGLAPI之glPolygonOffset函数详解 一 glPolygonOffset官方文档 glPo
  • Android Dalvik VM GC options 命令控制参数

    else if strncmp argv i Xgc 5 0 In VM thread there is a register map for marking each stack item s status whether it is a
  • YOLOv3的交通灯检测,ROS下实现交通灯检测一样只需要相应文件夹下面修改之后编译即可

    YOLOv3的交通灯检测 效果 只是需要修改源码image c即可修改如下 这里的0和9就是只检测行人和交通灯 对应的数字设置自己想检测的类型 可以查看coco names文件下 完成修改之后 make clean make j 重新编译即
  • MySQL常用的数据类型

    MySQL的常用数据类型包括 整型 Int TINYINT SMALLINT MEDIUMINT INT BIGINT 浮点型 Float FLOAT DOUBLE DECIMAL 字符串类型 String CHAR VARCHAR TEX
  • SpringBoot项目用 jQuery webcam plugin实现调用摄像头拍照并保存图片

    参考博客 http www voidcn com article p oigngyvb kv html 自定义样式
  • visual studio附加选项/Tc、/Tp、/TC、/TP(指定源文件类型)

    Tc 选项指定 filename 为 C 源文件 即使它没有 c 扩展名 Tp 选项指定 filename 为 C 源文件 即使它没有 cpp 或 cxx 扩展名 选项和 filename 之间的空格是可选的 每个选项指定一个文件 若要指定
  • 多元函数可微性知识点总结

    这节的知识点也挺多 主要就是可微和偏导数存在的关系 偏导数 z f x y z对x或者y的偏导数就是把另一个当做常数求导 还算简单 判断可微性 必要条件 可以写成偏导数都存在 且可以写成 d z f x d
  • 【Matlab】simlink自动生成嵌入式代码配置教程

    1 简介 最近在学习模型开发 相较于普通嵌入式代码开发来说 其能够进行仿真 并且能够使各模块之间的逻辑更加清晰 simlink自动生成代码过程较多 因此记录下来 方便日后参考 2 搭建simlink相关模块 3 进行求解器等相关配置 配置求
  • C++的四种强制转换

    1 static cast 基本等价于隐式转换的一种类型转换运算符 以前是编译器自动隐式转换 static cast可使用于需要明确隐式转换的地方 c 中用static cast用来表示明确的转换 可以用于低风险的转换 整型和浮点型 字符与
  • 量化交易的历史

    学习目标 了解量化交易的发展历史 量化交易全球的发展历史 量化投资的产生 60年代 1969年 爱德华 索普利用他发明的 科学股票市场系统 实际上是一种股票权证定价模型 成立了第一个量化投资基金 索普也被称之为量化投资的鼻祖 量化投资的兴起
  • bWAPP通关记录(A1)

    安装 这里使用的是phpstudy进行搭建的 先下载bWAPP 打开解压之后bWAPP目录下的admin中的settings php 将数据库连接名和密码改为与phpmyadmin相同的 保存 浏览器访问 点击here 点击Login 默认
  • kuka机器人焊接编程入门教程_焊接机器人操作编程与应用教学.pptx

    ABB MOTOMAN FANUC KUKA OTC机器人 第1章 机器人基础知识 第1章 机器人基础知识 第1章 机器人基础知识 第1章 机器人基础知识 第1章 机器人基础知识 第1章 机器人基础知识 第1章 机器人基础知识 第1章 机器
  • 小程序的文件结构

    小程序的文件结构 我们利用微信开发者工具创建一个新的小程序 会有包含一个描述整体程序的app和多个描述各自页面的page 一个小程序的主体部分由三个文件组成 必须放在项目的根目录 gt app js 小程序的主要逻辑判断 gt gt app

随机推荐

  • 重新学防抖debounce和节流throttle,及react hook模式中防抖节流的实现方式和注意事项

    重学节流和防抖 防抖 概念理解 防抖就是指触发事件后在 n 秒内函数只能执行一次 如果在 n 秒内又触发了事件 则会重新计算函数执行时间 举例说明 坐电梯的时候 如果电梯检测到有人进来 触发事件 就会多等待 10 秒 此时如果又有人进来 1
  • 300 倍的性能提升!PieCloudDB Database 优化器「达奇」又出新“招”啦

    随着数字化进程的加快 全球数据量呈指数级增长 对数据库系统的性能提出了巨大的挑战 优化器作为数据库管理系统中的关键技术 对数据库性能和效率具有重要影响 它通过对用户的查询请求进行解析和优化来生成高效的执行计划 进而快速返回查询结果 然而 同
  • 嵌入式Linux——oops:根据oops信息,找到错误的产生位置以及函数的调用关系

    简介 本文主要介绍通过oops信息找到程序中出错位置的方法 并结合自己代码中的错误来讲解如何找到出错位置 同时还会介绍使用栈信息来推到函数间的调用关系 Linux内核 linux 2 6 22 6 所用开发板 JZ2440 V3 S3C24
  • 一、【React基础】React简介及基本使用

    文章目录 1 官网 2 特点 3 相关js库 4 基本使用 4 1 CODE 4 2 Result 用于动态构建用户界面的 JavaScript 库 只关注于视图 由Facebook开源 1 官网 英文官网 https reactjs or
  • 广电用户画像分析之根据用户行为数据进行筛选与标签添加

    在数据处理和分析领域 我们经常需要根据用户的行为数据进行筛选和标签添加 以便更好地理解用户行为和偏好 在本篇博客中 我们将介绍两个示例 展示如何根据用户的收视行为数据和订单信息进行数据处理和分析 前情提要 数据集分析 广电用户画像分析之探索
  • Vue的学习

    一 Vue框架 常用地指令学习 https cn vuejs org 官网地址 概述 前端领域当中有三大框架 都是开发单页面应用的框架 Angular诞生于2009年 是由谷歌创建出来的框架 React诞生于2013年 是由facebook
  • idea无限build解决方案

    点击File Settings Build Excution Deploment Compiler勾上build project automatically
  • 【数据结构】树与二叉树总结(一)

    数据结构 树与二叉树的总结 一 1 AVL树 动态平衡二叉树 树表的查找 2 哈夫曼树 二叉树的应用 3 树 树与二叉树的转换 4 分裂树 5 S K R 注 K为结点 R为关系 一 树 定义 n n gt 0 个结点构成的有限集合 当n
  • SCSI硬盘

    SCSI硬盘即采用SCSI接口的硬盘 它由于性能好 稳定性高 因此在服务器上得到广泛应用 同时其价格也不菲 正因它的价格昂贵 所以在普通PC上很少见到它的踪迹 说到SCSI硬盘必须提到SCSI接口 SCSI是Small Computer S
  • MFC中窗口初始化时OnCreate、OnInitDialog、OnSize、OnPaint的 调用顺序

    执行顺序 以箭头方向 OnCreate gt OnSize gt OnInitDialog gt OnPaint OnCreate 要创建一个窗口 OnSize 用于窗口初始化前的一些参数设定 OnInitDialog 初始化窗口 例如设置
  • Jmeter录制脚本 模拟用户登录操作

    使用Jmeter测试web应用时 通常有两种测试计划 面向请求数的测试 面向场景的测试 模拟用户操作属于面向场景的测试 准备工作 1 1 建立线程组和HTTP请求 在测试计划中新建线程组 线程组中添加一个HTTP请求 并配置 1 2 录制控
  • 最小生成树总结1 prim算法

    最小生成树总结1 prim算法 最小生成树总结2 kurskal算法 文章目录 1 最小生成树问题概述 2 Prim算法流程 3 模板 4 板子题 1 最小生成树问题概述 给定带权节点网络 从中确定一个包含所有节点 n个 n 1条边 所有节
  • 机器学习到底是什么?

    关于机器学习最简单的定义来自于Berkeley所表述的 机器学习是AI的一个分支 它探索了让计算机根据经验提高效率的方法 为了更深刻的理解这一定义 接下来我们将对其进行拆分分析 AI的分支 人工智能是一种能够使得计算机及其系统能够成功完成通
  • MATLAB实现将数据写入到txt文件以及从txt文件中读取数据

    1 将数据写入到txt文件 global n global xm global ym xm 100 ym 100 global A global B n 10 A zeros 1 n B zeros 1 n for i 1 n A 1 i
  • 【Scala】scala ':' or newline expected \u200b

    1 背景 拷贝了网上一段代码 发现报错如下 这个是因为不可见字符 引起的 全局替换一下就好了 参考 IDEA IDEA报错 illegal character U 00A0异常解决
  • C++与C#类型转换例子

    C 部分类型定义 typedef struct SID AND ATTRIBUTES HASH DWORD SidCount PSID AND ATTRIBUTES SidAttr SID HASH ENTRY Hash SID HASH
  • Window11安装Docker Desktop(构建软链接解决Docker自动安装在C盘占用内存问题)

    一 查看电脑是否开启虚拟化 二 配置 Hyper V 三 构建软连接 使Dockor可以不安装在C盘 四 下载安装Dockor 五 配置环境 一 查看电脑是否开启虚拟化 打开设备管理器 gt 性能 gt CPU 查看是否开启虚拟化 若以开启
  • python中def main是什么意思_python - 为什么要使用def main()?

    其他人已经回答了 但我想我还有其他的东西需要补充 main 语句调用if的原因 无特定顺序 其他语言 如C和Java 具有main 函数 该函数在执行程序时调用 使用这个if 我们可以让Python像他们一样 这对许多人来说更为熟悉 代码将
  • python题库刷题网站_python在线刷题网站

    moduleinfo card count count phone 1 count 1 search count count phone 4 count 4 card des 阿里技术人对外发布原创技术内容的最大平台 社区覆盖了云计算 大数
  • java snack_Java 中 Snack3的使用

    网上看了一篇Java 中 Gson的使用 所以也跟着写篇Java 中 Snack3的使用 JSON 是一种文本形式的数据交换格式 从Ajax的时候开始流行 它比XML更轻量 比二进制容易阅读和编写 解析和生成的方式很多 Java中最常用的类