7.4 JSON支持

Limax提供完整的JSON支持(Java,C#,C++,Lua版本均提供与Javascript一致的JSON支持,使用上最大限度保证与javascript相同),便于同其它支持JSON的第三方系统进行交互。


  • 7.4.3 中继

    某些情况下,需要实现这样一种系统——接收来自上游系统的JSON串表示,解码该串执行设计要求的处理之后,将整个JSON元件或者JSON元件的一部分,作为本地系统的数据,重新打包为JSON串,传递给下游系统——JSON中继系统。

    • 实现(Javascript,Lua)

      脚本语言执行parse之后在名字空间内生成相应的对象层次结构。如果有中继需求,创建本地对象,按照相应语言的名字空间规范,引用或者部分引用解码结果,最后执行stringify即可。


    • 实现(Java,C#,C++)

      参见之前的类型映射表格最后一行可知, JSON编码器的输入参数,支持JSON解码器返回类型。也就是说parse/stringify可逆。

      parse/stringify可逆,即是实现JSON中继的关键,唯一需要注意的是,在JSON/Object或者JSON/Array上执行相应的get操作之后,返回的JSON对象isUndefined()测试为true的情况下,该返回对象不可中继,因为该对象并非来自上游系统,不可能存在一个正确表示,如果在这样的对象上执行stringify将抛出JSONException。


  • 7.4.4 异常规范

    为了确保程序健壮性,任何语言实现执行JSON编码解码操作,都必须考虑异常。

    • 编码异常

      1. 遭遇不可解释的字段类型,不可编码

      2. 遭遇isUndefined()测试为true的JSON对象

      3. 对象环引用

      4. 各种运行时异常,例如并发访问异常,字段读取失败


    • 解码异常

      1. JSON的串表示语法错误


    • 解码数据获取异常

      1. 不正确地访问JSON元件

      2. 数据类型转换失败

      3. 各种运行时异常,例如并发访问异常


    • Javascript的考虑

      1. 编码过程遭遇环,抛出异常;类型映射表不支持的类型被忽略,例如function

      2. 解码过程遭遇语法错误抛出异常

      3. 解码结果访问过程中,访问对象不存在的字段,访问数组越界,返回undefined,undefined上执行除bool测试,算术运算之外的访问抛出异常

      4. 应该用try {} catch(e) {} 方式捕获处理异常


    • Lua的考虑

      1. 编码过程遭遇环,抛出异常;类型映射表不支持的类型被忽略,例如function,userdata

      2. 解码过程遭遇语法错误抛出异常

      3. 解码结果访问过程中,访问对象不存在的字段,访问数组越界,返回nil,nil上执行除bool测试之外的访问抛出异常

      4. 应该使用pcall(function, args)方式捕获处理异常


    • Java,C#的考虑

      1. 编码过程遭遇环,抛出异常;遭遇类型映射表不支持的类型抛出异常;遭遇isUndefined()测试为true的JSON对象,抛出异常;并发访问异常。特别的,服务器端XBean如果支持JSONMarshal,与正常访问XBean规则一样,不能离开相应的锁,编码过程必须在事务环境中完成,否则抛出异常

      2. 解码过程遭遇语法错误抛出异常

      3. 解码结果访问过程中,访问对象不存在的字段,访问数组越界,返回isUndefined()测试为true的JSON对象,这样的对象上除了booleanValue(),isXXX()测试,toString()/ToString()操作外,抛出异常;非JSON/Object上get(string),keySet()抛出异常,非JSON/Array上get(int),toArray()/ToArrray()抛出异常;intValue(),longValue(), doubleValue()转换失败时抛出异常

      4. 各种类型的异常最终被JSONException包裹,所以应该使用try {} catch(JSONException e){}的方式捕获处理


    • C++的考虑

      1. C++不支持编码指针指向的对象,不可能出现环;遭遇类型映射表不支持的类型时,编译阶段就会报错;不考虑并发;所以仅在遭遇isUndefined()测试为true的JSON对象时抛出异常

      2. 解码过程遭遇语法错误抛出异常

      3. 解码结果访问过程中,访问对象不存在的字段,访问数组越界,返回isUndefined()测试为true的JSON对象,这样的对象上除了booleanValue(),isXXX()测试,toString()操作外,抛出异常;非JSON/Object上get(std::string),keySet()抛出异常,非JSON/Array上get(size_t),toArray()抛出异常;intValue(),longValue(),doubleValue()转换失败时抛出异常

      4. JSON操作抛出JSONException,应该使用try{} cache(JSONException e){} 方式捕获,e.message可获取抛出异常代码的行号,供debug使用


  • 7.4.5 字符集编码问题

    理论上看,JSON编码解码过程只对应字符串的输出输入,传输过程中这些字符串如何进行字节流的编码解码,不是JSON需要考虑的问题。然而,实际应用的设计很可能涉及到底层问题。

    • 理想情况

      发送端接收端使用兼容的字节流编码解码器,两边的JSON编码解码器均能获得正确的字符串表示,例如,limax通过Websocket与浏览器交互,两端均使用UTF8编码解码,JSON的使用不存在任何问题。


    • 较好情况(Java,C#)

      Java的java.nio.charset包,C#的System.Text.Encoding类,提供了完善的编解码器,如果有特殊需求,可以灵活适配对端系统。


    • 糟糕情况(C++, Lua)

      只支持UTF8,\uHHHH格式编码的Unicode字符在解码阶段被转换为UTF8。


上一页 下一页