课程章节介绍
同学们,咱们今天来看看Apex里一个很实用的功能——SON序列化。说白了,序列化就是把一个对象转成一串J-S-O-N格式的文本,方便我们在系统之间传数据,或者记日志,又或者在前端处理。
首先,Apex的SON序列化支持哪几类东西呢?
它很强大,普通的数据类型,比如字符串、数字、日期,还有集合里的列表、集合,都能序列化。最常用的是sObject,像Account、Contact这些标准或自定义的对象,直接就能转成JSON。还有数据库查询返回的结果容器,比如单个sObject或者列表,也支持。更棒的是,你完全可以自己写一个Apex类,里面定义几个属性,它也能被序列化,这样你就能把复杂的结构化数据打包成JSON发出去。
但是,这里面有几个坑得小心。
第一个限制:托管包里的Apex类实例,如果从包外面想要序列化它,对不起,不行。这是出于安全考虑,防止外部代码偷窥包里的数据结构。
第二个,如果你序列化一个Map,它对键的类型要求很严格,只能是那些简单的、可以直接排序的类型,像布尔值、日期、时间等等,复杂对象比如sObject绝对不行。
第三个,父子关系的问题很有意思。比如一个Account下面有Contacts,你把Account作为父对象序列化,它内嵌的子列表里每个Contact对象却会丢掉那些只在子类型里才有的字段。它只会保留Contact和Account共有的那部分属性,有点坑人。
还有,如果你试图序列化一个自引用的对象图,比如一个节点自己指向自己,Apex会抛出一个JSONResponse异常来保护你,阻止无限递归。即便你强行走通了,序列化出来的引用图其实是拷贝,不再是原对象引用关系。
最后,JSONParser这个类本身是不能被序列化的,你得用它来解析JSON,而不是把它打包进去。
再讲几个版本变迁中的行为差异,因为不同API版本编译的代码表现会不一样:
从API 63.0开始,如果代码执行中抛出了异常,你在序列化时不会把这个异常对象也转成JSON——它直接阻止这么做,这是为了避免敏感信息泄漏。
更早的API 53.0修复了一个日期时间精度的问题,之前可能损失毫秒,现在能精准保留了。
如果你用API 28.0以上版本,查询出的sObject在序列化时会自动带上关联查询的外键字段,但请注意,值为空的字段是不会出现的,这是为了减小JSON体积。
而API 34.0以下的版本里,有一个历史遗留问题:把一个序列化后的JSON再反序列化回来,对象的ID比较可能会失败,因为ID的内部结构不一样了。用新版本就没这烦恼。
记住这些规则,你在写集成或调试的时候就能少走很多弯路。好了,今天就说到这儿,大家可以在练习项目里动手试试,感受一下JSON序列化的方便与限制。
关键词
Apex
Salesforce
Developer Guide