openresty cjson解析json数据,



openresty cjson解析json数据

         

官网:https://github.com/mpx/lua-cjson

文档:https://kyne.com.au/~mark/software/lua-cjson-manual.html

             

                   

                                 

cjson 说明

         

cjson encode:编码为json数据

语法格式:json_text = cjson.encode(value)
* value可选类型:boolean、lightuserdata (NULL value only)
               nil、number、string、table
* 以下数据会报错:function、lightuserdata (non-NULL values)
               thread、userdata

Lua CJSON uses a heuristic to determine whether to encode a Lua table 
as a JSON array or an object. A Lua table with only positive integer 
keys of type number will be encoded as a JSON array. 
All other tables will be encoded as a JSON object
* table中只有正数,会被转换为json数组
* 含有非正数,会被转换为json object

# 示例
value = { true, { foo = "bar" } }
json_text = cjson.encode(value)

==> '[true,{"foo":"bar"}]'

         

cjson.encode_invalid_number:是否编译无效数字

语法格式:value = cjson.encode_invalid_numbers([setting])
* setting可选值:true、false(默认)、null
* 无效数字:无穷数、NaN(not a number)

true:编译无效数字,会产生不规则的json
null:将无效数字编译为null
false:不能编译无效数字,直接报错

      

cjson.encode_keep_buffer:复用编译缓存

语法格式:cjson.encode_keep_buffer([keep])
* keep可选值:true(默认)、false

true:复用编译缓存,可提升编译效率
false:每次调用encode后,清除缓存

              

cjson.encode_max_depth([depth]):编译的最大深度

语法格式:cjson.encode_max_depth([depth])
* 编译的最大深度默认为1000

# 示例:循环嵌套
a = {}; a[1] = a

            

cjson.encode_number_precision:数字编译精度

语法格式:cjson.encode_number_precision([precision])
* precision可选数字范围:1-14,默认14
* 将精度设小,可提升编译性能

             

cjson.encode_sparse_array:编译稀疏table

语法格式:cjson.encode_sparse_array([convert[, ratio[, safe]]])
* convert:boolean,默认false
* ration:正数,默认为2
* safe:正数,默认为10

# table分类:
normal:所有的值都存在
sparse:至少一个值不存在
extremely sparse:不存在的值的数量超过设置的比率

# extremely sparse判定条件
* ratio > 0
* maximum_index > safe
* maximum_index > item_count * ratio

By default, attempting to encode an excessively sparse array will 
generate an error. If convert is set to true, excessively sparse 
arrays will be converted to a JSON object.
* 默认情况下,编译excessively sparse table会报错
* convert设置为true,会转换为json object


# 示例
cjson.encode({ [3] = "data" }) ==> '[null,null,"data"]'

cjson.encode_sparse_array(true)
cjson.encode({ [1000] = "excessively sparse" })  
==> '{"1000":"excessively sparse"}'

          

                

                                 

使用示例

         

default.conf

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/local/openresty/nginx/html;
        index  index.html index.htm;
    }

    location /test {
        content_by_lua_block {
            local cjson = require 'cjson';
            local jsonStr = cjson.encode({
               a=1, b=2, c=3
            });

            ngx.say(jsonStr);
        }
    }

    location /test2 {
        content_by_lua_block {
            local cjson = require 'cjson';
            local jsonStr = cjson.encode({
               [1]=2, b=2, c=3
            });

            local jsonStr2 = cjson.encode({[100]=100, b=2});

            ngx.say(jsonStr);
            ngx.say(jsonStr2);
        }
    }

    location /test3 {
        content_by_lua_block {
            local cjson = require 'cjson';

            --cjson.encode_sparse_array(true);
            local jsonStr = cjson.encode({
               [1]=2, [2]=2
            });

            local jsonStr2 = cjson.encode({[100]=100});

            ngx.say(jsonStr);
            ngx.say(jsonStr2);
        }
    }
    
    location /test4 {
        content_by_lua_block {
            local cjson = require 'cjson';

            cjson.encode_sparse_array(true);
            local jsonStr = cjson.encode({
               [1]=2, [2]=2
            });

            local jsonStr2 = cjson.encode({[100]=100});

            ngx.say(jsonStr);
            ngx.say(jsonStr2);
        }
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/local/openresty/nginx/html;
    }
}

         

创建容器

docker run -it -d -p 5001:80 \
-v /Users/huli/lua/openresty/cjson/default.conf:/etc/nginx/conf.d/default.conf \
--name cjson lihu12344/openresty

        

使用测试

# 编码table数据
huli@hudeMacBook-Pro cjson % curl localhost:5001/test 
{"a":1,"c":3,"b":2}

# 非纯稀疏数组
huli@hudeMacBook-Pro cjson % curl localhost:5001/test2
{"1":2,"b":2,"c":3}
{"100":100,"b":2}

# 纯稀疏数组,如果没有开启encode_sparse_array,达到extremely sparse会报错
huli@hudeMacBook-Pro cjson % curl localhost:5001/test3
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Error</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>An error occurred.</h1>
<p>Sorry, the page you are looking for is currently unavailable.<br/>
Please try again later.</p>
<p>If you are the system administrator of this resource then you should check
the <a href="http://nginx.org/r/error_log">error log</a> for details.</p>
<p>We have articles on troubleshooting issues like <a href="https://blog.openresty.com/en/lua-cpu-flame-graph/?src=wb">high CPU usage</a> and
<a href="https://blog.openresty.com/en/how-or-alloc-mem/">large memory usage</a> on <a href="https://blog.openresty.com/">our official blog site</a>.
<p><em>Faithfully yours, <a href="https://openresty.org/">OpenResty</a>.</em></p>
</body>
</html>


# cjson.encode_sparse_array(true)
huli@hudeMacBook-Pro cjson % curl localhost:5001/test4
[2,2]
{"100":100}

                    

extremely sparse报错信息

2022/07/13 01:34:20 [error] 8#8: *3 lua entry thread aborted: runtime error: content_by_lua(default.conf:48):9: Cannot serialise table: excessively sparse array
stack traceback:
coroutine 0:
	[C]: in function 'encode'
	content_by_lua(default.conf:48):9: in main chunk, client: 172.17.0.1, server: localhost, request: "GET /test3 HTTP/1.1", host: "localhost:5001"
172.17.0.1 - - [13/Jul/2022:01:34:20 +0000] "GET /test3 HTTP/1.1" 500 982 "-" "curl/7.77.0"

         

                   

相关内容