alibaba / fastjson

FASTJSON 2.0.x has been released, faster and more secure, recommend you upgrade.
https://github.com/alibaba/fastjson2/wiki/fastjson_1_upgrade_cn
Apache License 2.0
25.74k stars 6.5k forks source link

JSONArray.parseObject时,忽略JSONField注解信息 #2918

Open insaneXs opened 4 years ago

insaneXs commented 4 years ago

我有一个类,通过自定义序列化和反序列化器定制了其在序列化和反序列化的过程。

我把这个类放进JSONArray序列化输出字符串后,自定义的序列化器能正常工作。
但是当我序列化后的字符串在反序列化时,发现自定义的反序列化器失效了。

断点调试时,发现反序列化过程是走了JavaBeanDeserializer.createInstance方法。
createIntance在反序列化时不获取目标类上字段是否有@JSONField。

而假设我们在序列化时,直接将对象序列化,再将得到的字符串反序列化, 反序列化过程走的是JavaBeanDeserializer.deserialize的方法。

这个方法会在反序列化的时候搜集字段上的@JSONField信息, 如果通过@JSONField指定了反序列化器,那么会用反序列化器执行字段的反序列化过程。

问题是,同样都是反序列化过程,为什么JSON.parseObject和JSONArray.parseObject表现的行为不一样? 关于createInstance和deserialize两个方法,又是怎么定义的?

没有大佬回答,只好在把测试代码补上了。

protected static void testJSONArrayParse(){
        System.out.println("**************Start Test JSONArray Parse");
        JSONArray arr = new JSONArray();
        Article originArticle = new Article("Article 1", "This is content", AuditStatus.AUDITING);
        arr.add(originArticle);

        String jsonArrStr = JSON.toJSONString(arr);
        System.out.println("Serialize to json array string: " + jsonArrStr);

        arr = JSON.parseArray(jsonArrStr);
        Article deserializeArticle = arr.getObject(0, Article.class);

        System.out.println("Deserialize to json arr, then to java object: " + deserializeArticle + "; and the status is " + deserializeArticle.getStatus());
        //Not Equals
        Assert.assertFalse(deserializeArticle.getStatus().equals(AuditStatus.AUDITING));
        Assert.assertNotEquals(originArticle, deserializeArticle);
    }

控制台输出的情况是:

Serialize to json array string: [{"content":"This is content","status":1,"title":"Article 1"}]
Deserialize to json arr, then to java object: Article{title='Article 1', content='This is content', status=PASSED}; and the status is PASSED

可以看到反序列化前枚举是AUDITING,反序列化后得到PASSED

610983691 commented 2 years ago

有继承吗