delphi12开始提供JSON支持。我在delphi15测试datasnap REST服务器。
先看看JSON序列化的能力:
RTTI很强大了,连Private部分的也进入了RTTI,而且不用调用RegisterClass(TtmObject),在反序列化时也能创建出TtmObject元件。
还是不支持Variant类型,如果自己需要,需要修改DBXJSONReflect.pas的MarshalSimpleField函数,遗憾的是这些函数都不是虚函数,否则可以继承。当然,理论上你不需要支持variant,完全可以用Object作为property,即以嵌套的形式实现异质资料的组合效果。
我注意到序列化后的结果:{"type":"UnitClient.TtmObject","id":1,"fields":{"FName":"wxh","FAge":35,"FBirthday":26997,"FClasses":["shanghai","chongqing","beijing"]}}
其中日期类型是编码为JSON的Number,不同语言的日期起点可能不一样,所以如果跨语言使用,这里需要注意。
但是,我发现在ServerMethod中如果返回TDateTime,却是以string来编码的,如:
注意TJSONARRAY的destroy,每个Element预设会被释放:
因此需要当心,创建了TJSONValue然后加到JSONArray后,不要再自己释放,如果自己要释放,那么加入前先把Owned置为false。
所以在ServerMethod处理CallBack的时候,同样要注意这个问题:
应该自己用try finally来释放比较安全,因为难保在ACallBack.Execute里面,在释放你的S前出现Exception,那么就会出现内存泄漏了,因此我建议Delphi不要这样处理,留下陷阱,要么是完整的垃圾回收,要么让程序员自己回收。
CallBack功能很棒,原来在DCOM的时候有CallBack,WebService的时候又没有了。
另一个问题是,如果使用http get,当ServerMethod出现av错误时,客户端得不到明确的错误信息,只会得到:
HTTP/1.1 500 Internal Server Error.