openresty開發系列25--openresty中使用json模塊
web開發過程中,經常用的數據結構為json,openresty中封裝了json模塊,我們看如何使用
一)如何引入cjson模塊,需要使用require
local json = require("cjson")
json.encode 將表格數據編碼為 JSON 字符串
格式:
jsonString = json.encode(表格對象)
用法示例:
table 包含哈希鍵值對 和 數組鍵值對
-------------------test.lua--------------
1)table包含哈希鍵值對時,數組鍵值將被轉換為字符串鍵值
local json = require("cjson")
local t = {1,3,name="張三",age="19",address={"地址1","地址2"},sex="女"}
ngx.say(json.encode(t));
ngx.say("<br/>");
----{"1":1,"2":3,"sex":"女","age":"19","address":["地址1","地址2"],"name":"張三"}
local str = json.encode({a=1,[5]=3})
ngx.say(str); ----- {"a":1,"5":3}
ngx.say("<br/>");
2)table所有鍵為數組型鍵值對時,會當作數組看待,空位將轉化為null
local str = json.encode({[3]=1,[5]=2,[6]="3",[7]=4})
ngx.say(str); ---- [null,null,1,null,2,"3",4]
ngx.say("<br/>");
local str = json.encode({[3]=2,[5]=3})
ngx.say(str); ---- [null,null,2,null,3]
ngx.say("<br/>");
----------------------------------------
json.decode 將JSON 字符串解碼為表格對象
格式:
table = json.decode(string)
用法示例:
local str = [[ {"a":"v","b":2,"c":{"c1":1,"c2":2},"d":[10,11],"1":100} ]]
local t = json.decode(str)
ngx.say(" --> ", type(t))
-------------
local str = [[ {"a":1,"b":null} ]]
local t = json.decode(str)
ngx.say(t.a, "<br/>")
ngx.say(t.b == nil, "<br/>")
ngx.say(t.b == json.null, "<br/>")
----> 1
----> false
----> true
注意:null將會轉換為json.null
二)異常處理
local json = require("cjson")
local str = [[ {"key:"value"} ]]---少了一個雙引號
local t = json.decode(str)
ngx.say(" --> ", type(t))
執行請求,看看效果,執行報了--500 Internal Server Error
是因為decode方法報錯了導致
實際情況我們希望的結果不是報錯,而是返回一個友好的結果,如返回個nil
使用pcall命令
如果需要在 Lua 中處理錯誤,必須使用函數 pcall(protected call)來包裝需要執行的代碼。
pcall 接收一個函數和要傳遞給后者的參數,並執行,執行結果:有錯誤、無錯誤;
返回值 true 或者或 false, errorinfo。
pcall 以一種"保護模式"來調用第一個參數(函數),因此 pcall 可以捕獲函數執行中的任何錯誤。
第一個方案:重新包裝一個 json decode編碼
local json = require("cjson")
local function _json_decode(str)
return json.decode(str)
end
function json_decode( str )
local ok, t = pcall(_json_decode, str)
if not ok then
return nil
end
return t
end
local str = [[ {"key:"value"} ]]---少了一個雙引號
local t = json_decode(str)
ngx.say(t)
執行效果,沒有系統錯誤,返回了nil
第二個方案:引入cjson.safe 模塊接口,該接口兼容 cjson 模塊,並且在解析錯誤時不拋出異常,而是返回 nil。
local json = require("cjson.safe")
local str = [[ {"key:"value"} ]]
local t = json.decode(str)
if t then
ngx.say(" --> ", type(t))
else
ngx.say("t is nil")
end
三)空table返回object還是array
測試一下,編碼空table {}
local json = require("cjson")
ngx.say("value --> ", json.encode({}))
輸出 value --> {}
{}是個object;對於java的開發人員來說就不對了,空數組table,應該是[]
這個是因為對於 Lua 本身,是把數組和哈希鍵值對融合到一起了,所以他是無法區分空數組和空字典的。
要達到目標把 encode_empty_table_as_object 設置為 false
local json = require("cjson")
json.encode_empty_table_as_object(false)
ngx.say("value --> ", json.encode({}))
輸出 value --> []