Lua Json使用
在进行数据传输时JSON格式目前应用广泛,因此从Lua对象与JSON字符串之间相互转换是一个非常常见的功能;目前Lua也有几个JSON库,如:cjson、dkjson。其中cjson的语法严格(比如unicode \u0020\u7eaf),要求符合规范否则会解析失败(如\u002),而dkjson相对宽松,当然也可以通过修改cjson的源码来完成一些特殊要求。而在使用dkjson时也没有遇到性能问题,目前使用的就是dkjson。使用时要特别注意的是大部分JSON库都仅支持UTF-8编码;因此如果你的字符编码是如GBK则需要先转换为UTF-8然后进行处理。
1.1 test_cjson.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| local cjson = require("cjson")
local obj = { id = 1, name = "zhangsan", age = nil, is_male = false, hobby = {"film", "music", "read"} }
local str = cjson.encode(obj) ngx.say(str, "<br/>")
str = '{"hobby":["film","music","read"],"is_male":false,"name":"zhangsan","id":1,"age":null}' local obj = cjson.decode(str)
ngx.say(obj.age, "<br/>") ngx.say(obj.age == nil, "<br/>") ngx.say(obj.age == cjson.null, "<br/>") ngx.say(obj.hobby[1], "<br/>")
obj = { id = 1 } obj.obj = obj
local cjson_safe = require("cjson.safe")
ngx.say(cjson_safe.encode(obj), "<br/>")
|
null将会转换为cjson.null;循环引用会抛出异常Cannot serialise, excessive nesting,默认解析嵌套深度是1000,可以通过cjson.encode_max_depth()设置深度提高性能;使用cjson.safe不会抛出异常而是返回nil。
1.2 openResty.conf配置文件
1 2 3 4 5
| location ~ /lua_cjson { default_type 'text/html'; lua_code_cache on; content_by_lua_file /usr/openResty/json/lua/test_cjson.lua; }
|
1.3 查看结果
1 2 3 4 5 6
| {"is_male":false,"name":"zhangsan","hobby":["film","music","read"],"id":1} null false true film nil
|
lua-cjson文档http://www.kyne.com.au/~mark/software/lua-cjson-manual.html。
接下来学习下dkjson。
2.1 下载dkjson库
1 2
| cd /usr/openResty/lualib wget http://dkolf.de/src/dkjson-lua.fsl/raw/dkjson.lua?name=16cbc26080996d9da827df42cb0844a25518eeb3 -O dkjson.lua
|
2.2 test_dkjson.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| local dkjson = require("dkjson")
local obj = { id = 1, name = "zhangsan", age = nil, is_male = false, hobby = {"film", "music", "read"} }
local str = dkjson.encode(obj, {indent = true}) ngx.say(str, "<br/>")
str = '{"hobby":["film","music","read"],"is_male":false,"name":"zhangsan","id":1,"age":null}' local obj, pos, err = dkjson.decode(str, 1, nil)
ngx.say(obj.age, "<br/>") ngx.say(obj.age == nil, "<br/>") ngx.say(obj.hobby[1], "<br/>")
obj = { id = 1 } obj.obj = obj
|
默认情况下解析的json的字符会有缩排和换行,使用{indent = true}配置将把所有内容放在一行。和cjson不同的是解析json字符串中的null时会得到nil。
2.3 openResty.conf配置文件
1 2 3 4 5
| location ~ /lua_dkjson { default_type 'text/html'; lua_code_cache on; content_by_lua_file /usr/openResty/lua/json/test_dkjson.lua; }
|
2.4 查看结果
1 2 3 4
| { "is_male":false, "name":"zhangsan", "hobby":["film","music","read"], "id":1 } nil true film
|
dkjson文档http://dkolf.de/src/dkjson-lua.fsl/home和http://dkolf.de/src/dkjson-lua.fsl/wiki?name=Documentation。