fastjson 序列化踩坑

坑1:包含转义符的子对象反序列化

场景

这样一个 json 字符串

[ {
  "value" : "定位标志:0,GPS:9,POWER:1,GSM:15",
  "name" : "positionType",
  "metadata" : "{\"timestamp\":1735119664668}"
} ]

这个 json 字符串是如何产生的?
metadata 对应的是一个由 Java 对象序列化得到的 json 字符串,这个字符串本身就包含了""
当使用 RedisTemplate 用 String 形式写入 Redis 存储时会对""进行转义
理论上再使用 RedisTemplate 将其读出的时候会自动处理转义符
但是由于一组操作的原子性考量我使用了 Lua 脚本去读,这样就是存储的原样读取没有处理转义符

问题

问题在哪里?

通常来说这两种写法是等价的

// 第一种
JSON.parseArray(propertiesStr).stream()
                .map(jsonObject -> JSONObject.toJavaObject((JSONObject) jsonObject, PropertyDTO.class))
                .toList();
// 第二种就是上面写法的优化简化版本,通常是这样
JSON.parseArray(propertiesStr, PropertyDTO.class);

但事实上对于我上面给到的子对象带转义符的 json 字符串,第一种没问题,第二种会报错

无论我将 metadata 的类型定义为对象还是 String 都会报错

为什么?

如何应对?

坑2:序列化和反序列化遇上多态

场景

Son son = new Son(21, "张三");
// 问题1:父类引用指向子类对象,然后序列化父类得到的是否包含子类属性
Father father = son;
System.out.println(JSON.toJSONString(father));
// 问题2:子类子字符串反序列化为父类是否会失败报错?
String sonStr = JSON.toJSONString(son, SerializerFeature.WriteClassName);
Father father2 = JSON.parseObject(sonStr, Father.class);

问题

答案是什么?

1 会成功,序列化父类引用得到的 json 字符串包含了子类所有的属性

2 会报错

为什么?

如何应对?

坑3:数组对象的序列化不要多此一举先转字符串

// 会打印{"key":[]},JSONArray也是
json.put("key",new ArrayList<>());
System.out.println(json.toJSONString());

// 会打印{"key":"[]"},错误
json.put("key",new JSONArray.toString());
System.out.println(json.toJSONString());
posted @ 2024-12-31 16:23  YaosGHC  阅读(140)  评论(0)    收藏  举报