[BUG]序列化时子类型字段丢失
- Dominant language
- Java
- Stars
- 4.4k
- Forks
- 613
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 6
Description
### 问题描述
json序列化JSON.toJSONString(object),当bean中属性保存的实例是子类型时,可能引发序列化结果中子类型的属性丢失
### 环境信息
- 版本信息:[Fastjson2 2.0.48及以上]
### 重现步骤
@Getter
@Setter
public static class A {
private String fieldA;
}
@Getter
@Setter
public static class B extends A {
private String fieldB;
}
@Getter
@Setter
public static class Bean{
private A filed;
}
public static void main(String[] args) {
A a = new A();
a.setFieldA("aaa");
Bean bean1 = new Bean();
bean1.setFiled(a);
B b = new B();
b.setFieldA("aaa");
b.setFieldB("bbb");
Bean bean2 = new Bean();
bean2.setFiled(b);
// 此处输出{"filed":{"fieldA":"aaa"}}
System.out.println(com.alibaba.fastjson2.JSONObject.toJSONString(bean1));
// 此处输出{"filed":{"fieldA":"aaa"}},更换toJsonString顺序则输出{"filed":{"fieldA":"aaa","fieldB":"bbb"}}
System.out.println(com.alibaba.fastjson2.JSONObject.toJSONString(bean2));
}
### 期待的正确结果
*对您期望发生的结果进行清晰简洁的描述。*
### 相关日志输出
*请复制并粘贴任何相关的日志输出。*
#### 附加信息
JSONFactory.defaultObjectWriterProvider中有个全局的cache用于保存ObjectWriter实例,当bean第一次序列化时,生成ObjectWriter实例并放入cache,后续序列化时使用缓存的ObjectWriter实例,对于这个bean的field也会生成对应的FieldWriterObject保存在ObjectWriter实例中,field序列化时会判断初始化的class和当前的class是否匹配,匹配就使用已有的FieldWriterObject,不匹配就生成新的FieldWriterObject
2.0.48的匹配逻辑增加了initValueClass.isAssignableFrom(valueClass),导致如果从第二次开始存放子类型,使用的FieldWriterObject是父类型的,序列化结果中就会丢失子类型的属性
https://github.com/alibaba/fastjson2/commit/7d974f3024e5cebda4392b65c1e47f10cc239f70
Contributor guide
Research direction
Start with JSONFactory.defaultObjectWriterProvider and the FieldWriterObject matching logic described in the issue, then review commit 7d974f3024e5cebda4392b65c1e47f10cc239f70. Reproduce the supplied A, B, and Bean example with both serialization orders; done means the subtype fieldB is retained consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100