高併發 Nginx+Lua OpenResty系列(7)——Lua開發庫json

JSON庫

在進行數據傳輸時JSON格式目前應用普遍,所以從Lua對象與JSON字符串之間相互轉換是一個很是常見的功能;目前Lua也有幾個JSON庫,如:cjson、dkjson。其中cjson的語法嚴格(好比unicode \u0020\u7eaf),要求符合規範不然會解析失敗(如\u002),而dkjson相對寬鬆,固然也能夠經過修改cjson的源碼來完成一些特殊要求。而在使用dkjson時也沒有遇到性能問題,目前使用的就是dkjson。使用時要特別注意的是大部分JSON庫都僅支持UTF-8編碼;所以若是你的字符編碼是如GBK則須要先轉換爲UTF-8而後進行處理。html

1.1 test_cjson.lua

local cjson = require("cjson")

--lua對象到字符串
local obj = {
    id = 1,
    name = "zhangsan",
    age = nil,
    is_male = false,
    hobby = {"film", "music", "read"}
}

local str = cjson.encode(obj)
ngx.say(str, "<br/>")

--字符串到lua對象
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
-- Cannot serialise, excessive nesting
--ngx.say(cjson.encode(obj), "<br/>")
local cjson_safe = require("cjson.safe")
--nil
ngx.say(cjson_safe.encode(obj), "<br/>")

null將會轉換爲cjson.null;循環引用會拋出異常Cannot serialise, excessive nesting,默認解析嵌套深度是1000,能夠經過cjson.encode_max_depth()設置深度提升性能;使用cjson.safe不會拋出異常而是返回nil。web

1.2 openResty.conf配置文件

location ~ /lua_cjson {
        default_type 'text/html';
        lua_code_cache on;
        content_by_lua_file /usr/openResty/json/lua/test_cjson.lua;
    }

1.3 查看結果

{"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。json

2.1 下載dkjson庫

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

local dkjson = require("dkjson")

--lua對象到字符串
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/>")

--字符串到lua對象
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
--reference cycle
--ngx.say(dkjson.encode(obj), "<br/>")

默認狀況下解析的json的字符會有縮排和換行,使用{indent = true}配置將把全部內容放在一行。和cjson不一樣的是解析json字符串中的null時會獲得nil。svg

2.3 openResty.conf配置文件

location ~ /lua_dkjson {  
        default_type 'text/html';
        lua_code_cache on;
        content_by_lua_file /usr/openResty/lua/json/test_dkjson.lua;
    }

2.4 查看結果

{ "is_male":false, "name":"zhangsan", "hobby":["film","music","read"], "id":1 }
nil
true
film

dkjson文檔http://dkolf.de/src/dkjson-lua.fsl/homehttp://dkolf.de/src/dkjson-lua.fsl/wiki?name=Documentation性能

相關文章
相關標籤/搜索