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。
-