json数据处理
一、JSON 介绍
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人类阅读和编写,同时也易于机器解析和生成。它基于 JavaScript 编程语言的一个子集,但独立于语言,广泛用于不同编程环境中。
1.1 JSON 的基本结构
1.1.1 对象
由花括号 {}
包围,包含键值对。键是字符串,值可以是字符串、数字、布尔值、数组、对象或 null
。 { "name": "Alice", "age": 30, "isStudent": false }
1.1.2 数组
由方括号 []
包围,包含一个有序的值列表。值可以是任何类型的数据,包括对象和其他数组。 [ "apple", "banana", "cherry" ]
1.2 JSON 的优点
简洁性:结构简单,易于理解和使用。
可移植性:语言无关,几乎所有的编程语言都支持 JSON 解析和生成。
灵活性:适用于各种数据结构的表示。
1.3 常用场景
Web 应用:用于客户端与服务器之间的数据交换。
配置文件:用于应用程序的配置设置。
数据存储:用于存储简单的数据结构。
综上所述,JSON 因其简单和灵活的特性,已经成为现代编程中数据交换的标准格式之一。
二、演示功能概述
本 demo 通过使用 Air8101 开发板,生成与解析 JSON 格式数据,并通过日志观察实验结果。
三、准备硬件环境
“古人云:‘工欲善其事,必先利其器。’在深入介绍本功能示例之前,我们首先需要确保以下硬件环境的准备工作已经完成。”
参考:硬件环境清单,准备以及组装好硬件环境。
四、软件环境
“凡事预则立,不预则废。”在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。
- Luatools 工具;
- 内核固件文件(底层 core 固件文件):LuatOS-SoC_V10001_Air8101.soc;参考项目使用的内核固件;
- luatos 需要的脚本和资源文件
脚本和资源文件:https://gitee.com/openLuat/LuatOS-Air8101/tree/master/demo/wlan/softAP
lib 脚本文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件;
准备好软件环境之后,接下来查看如何烧录项目文件到 Air8101 开发板,将本篇文章中演示使用的项目文件烧录到 Air8101 开发板中。
五、API 介绍
5.1 json 编译
json.encode(torigin)
JSON 有自己规定的格式,一点的格式错误都无法 JSON 解析出有效数据。这里我们提供了 JSON 编译函数,你只需要把有效数据放入 table 类型的变量中,然后传入 JSON 编译函数 json.encode(table 类型变量),他就会返回 JSON 有效字符串。
参数
**参数** | **类型** | **释义** | **取值** |
torigin | table | 待编译的源字符 |
返回值
**返回值** | **类型** | **释义** | **取值** |
res | string | json格式字符串 |
例子
local torigin =
{
KEY1 = "VALUE1",
KEY2 = "VALUE2",
KEY3 = "VALUE3",
KEY4 = "VALUE4",
KEY5 = {KEY5_1="VALU5_1",KEY5_2="VALU5_2"},
KEY6 = {1,2,3},
}
local jsondata = json.encode(torigin)
5.2 json 解析
json.decode(origin)
JSON 解析也很简单,有解析函数 json.decode(origin),origin 是待解析的 JSON 字符串。他会返回三个值(解析的内容,解析结果,错误信息)当 JSON 有效字符串被解析后,有效的数据就会被放在 table 的变量里,你需要定义一个变量接收一下。接着你就可以对 table 变量处理获取有效值。
参数
**参数** | **类型** | **释义** | **取值** |
torigin | table | 待解析的json字符串 |
返回值
**返回值** | **类型** | **释义** | **取值** |
res | string | 解析内容,table类型;解析结果,true为成功,false为失败;错误信息 |
例子
_-- 正确json字符串_local wrongOrigin = "{\":\"VALUE3\",\"KEY4\":\"VALUE4\",\"KEY2\":\"VALUE2\",\"KEY1\":\"VALUE1\",\"KEY5\":{\"KEY5_2\":\"VALU5_2\",\"KEY5_1\":\"VALU5_1\"},\"KEY6\":[1,2,3]}"local origin = "{\"KEY3\":\"VALUE3\",\"KEY4\":\"VALUE4\",\"KEY2\":\"VALUE2\",\"KEY1\":\"VALUE1\",\"KEY5\":{\"KEY5_2\":\"VALU5_2\",\"KEY5_1\":\"VALU5_1\"},\"KEY6\":[1,2,3]}"local tjsondata,result,errinfo = json.decode(origin)
if result thenprint(tjsondata["KEY1"])print(tjsondata["KEY2"])print(tjsondata["KEY3"])print(tjsondata["KEY4"])print(tjsondata["KEY5"]["KEY5_1"],tjsondata["KEY5"]["KEY5_2"])print(tjsondata["KEY6"][1],tjsondata["KEY6"][2],tjsondata["KEY6"][3])
elseprint("json.decode error",errinfo)
end
六、代码示例介绍
6.1 核心代码详解
6.1.1 将 Lua 表编码为 JSON 字符串
lua
local t = {abc=123, def="123", ttt=true}
local jdata = json.encode(t)
log.info("json", jdata) -- 日志输出:{"ttt":true,"def":"123","abc":123}
- 通过
json.encode(t)
将 Lua 表t
转换为 JSON 字符串。 - 输出的 JSON 字符串会在日志中显示。注意,JSON 的键值对顺序并不固定,可能与 Lua 表的顺序不同。
6.1.2 将 JSON 字符串解码为 Lua 表
lua
local str = "{\"abc\":1234545}"local t = json.decode(str)
if t thenlog.info("json", "decode", t.abc) -- 日志输出:decode 1234545elselog.info("json", "decode failed")
end
json.decode(str)
尝试将 JSON 字符串转换为 Lua 表。如果转换成功,输出表中abc
的值。如果失败,输出 "decode failed"。
6.1.3 混合类型表编码问题
lua
t.abc.def = "123"
t.abc[1] = 345log.info("json", "encode2", json.encode(t)) -- 日志输出:{"abc":{"1":345,"def":"123"}}
- 这里的
t.abc
是一个混合类型的表,既包含了整数键1
,也包含了字符串键def
。编码后的 JSON 表示为对象而非数组,因为 JSON 对象是以键值对的形式表示数据。
6.1.4 浮点数编码
lua
log.info("json", json.encode({abc=1234.300})) -- 日志输出:{"abc":1234.300}log.info("json", json.encode({abc=1234.300}, "1f")) -- 日志输出:{"abc":1234.3}
json.encode
可以编码浮点数。在第二个例子中,使用"1f"
参数将浮点数限制为最多一位小数。
6.1.5 特殊字符处理
lua
local tmp = "ABC\r\nDEF\r\n"local tmp2 = json.encode({str=tmp})
log.info("json", tmp2) -- 日志输出:{"str":"ABC\r\nDEF\r\n"}
\r\n
是回车换行符,在 JSON 编码中,它会被保留作为字符串的一部分。
lua
local tmp3 = json.decode(tmp2)
log.info("json", "tmp3", tmp3.str, tmp3.str == tmp) -- 日志输出:tmp3 ABC-- DEF-- true
- 解码后的 JSON 字符串保持了原始的换行符,并且通过比较验证它们相等。
6.2 完整程序清单
注:完整复制后保存为 main.lua,可直接使用
-- main.lua文件
-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "json_demo"
VERSION = "1.0.0"
-- sys库是标配
sys = require("sys")
log.info("main", PROJECT, VERSION)
-- json库支持将 table 转为 字符串, 或者反过来, 字符串 转 table
-- 若转换失败, 会返回nil值, 强烈建议在使用时添加额外的判断
sys.taskInit(function()
sys.wait(1000)
-- table 转为 字符串
local t = {abc=123, def="123", ttt=true}
local jdata = json.encode(t)
log.info("json", jdata) --日志输出:{"ttt":true,"def":"123","abc":123}
-- 字符串转table
local str = "{\"abc\":1234545}" -- 字符串可以来源于任何地方,网络,文本,用户输入,都可以
local t = json.decode(str)
if t then
-- 若解码成功,t不为nil
log.info("json", "decode", t.abc) --日志输出:decode 1234545
else
-- 若解码失败,t为nil
log.info("json", "decode failed")
end
-- lua中的table是 数组和hashmap的混合体
-- 这对json来说会有一些困扰, 尤其是空的table
local t = {abc={}}
-- 假设从业务上需要输出 {"abc":[]}
-- 实际会输出 {"abc": {}} , 空table是优先输出 hashmap (即字典模式)形式, 而非数组形式,Lua语言中数组优先级低于hashmap优先级
log.info("json", "encode", json.encode(t)) --日志输出:encode {"abc":{}}
-- 混合场景, json场景应避免使用
t.abc.def = "123"
t.abc[1] = 345
-- 输出的内容是 {"abc":{"1":345,"def":"123"}}
log.info("json", "encode2", json.encode(t)) --日志输出:encode2 {"abc":{"1":345,"def":"123"}}
-- 浮点数演示
log.info("json", json.encode({abc=1234.300}))--日志输出:{"abc":1234.300}
-- 限制小数点到1位
log.info("json", json.encode({abc=1234.300}, "1f")) --日志输出:{"abc":1234.3}
local tmp = "ABC\r\nDEF\r\n"
local tmp2 = json.encode({str=tmp}) --在JSON中,\r\n 被保留为字符串的一部分
log.info("json", tmp2) --日志输出:{"str":"ABC\r\nDEF\r\n"}
local tmp3 = json.decode(tmp2)
log.info("json", "tmp3", tmp3.str, tmp3.str == tmp) --日志输出:tmp3 ABC
--DEF
-- true 注:true前存在一个TAB长度(这个TAB原因未知,但不影响使用)
-- break
log.info("json.null", json.encode({name=json.null})) --日志输出:{} 为空对象
log.info("json.null", json.decode("{\"abc\":null}").abc == json.null) --日志输出:false 在 Lua 中,nil 是一种特殊类型,用于表示“无值”或“未定义”。它与任何其他值(包括自定义的 json.null)都不相等
log.info("json.null", json.decode("{\"abc\":null}").abc == nil) --日志输出:false
end)
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
七、功能验证
7.1 下载固件的基本设置
7.2 table 转为 字符串
7.3 字符串转 table
7.4 混合场景输出
7.5 浮点数演示
7.6 特殊字符处理
总结
至此,我们已使用 Air8101 开发板验证了 JSON 编、解码功能。