[alibaba/fastjson]使用了@JsonType序列化之后反序列化失败

2024-10-16 659 views
4

序列化的时候使用SerializerFeature.WriteClassName, 类上使用了@JSONType, 能成功序列化, 但是反序列化时失败, 使用版本为1.2.60 ;

异常信息为: Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error 无法识别"@type"

示例如下:

` public class TestJSon {

@Data
@JSONType(typeName = "BigDog")
static class Dog {
    private Map<String, Food>  foodMap;
}

@Data
@JSONType(typeName = "BigFood")
static class Food {
    private String name;
}

@Data
@JSONType(typeName = "iPhone")
static class Apple extends Food {
    private String colour;
}

public static void main(String[] args){
    ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
    TestJSon.Dog dog = new TestJSon.Dog();
    Map<String, TestJSon.Food> foodMap = new HashMap<>();
    TestJSon.Apple a = new TestJSon.Apple();
    a.setColour("red");
    foodMap.put("a",a);
    dog.setFoodMap(foodMap);

    String jsonString = JSON.toJSONString(dog, SerializerFeature.WriteClassName);
    System.out.println(jsonString);
    System.out.println(JSON.parseObject(jsonString,Dog.class));
}

} `

回答

3

setSingleMap 是啥。。。没定义呀,亲

4

setSingleMap 是啥。。。没定义呀,亲

sorry, 改了

2

你可以把JSON.parseObject(jsonString,Dog.class) 换成com.alibaba.fastjson.JSON.parseObject(jsonString) 或者 com.alibaba.fastjson.JSON.parse(jsonString)试试。而且在你的例子中你是使用了Lombok的注解吗?如果是使用了第三方依赖库的东西,最好可以说明一下,哪怕这个依赖库很出名。@Bearin

4

@OLPMO 不好意思, 补充下, 使用了Lomok, 版本为1.16.18; 在fastjson的1.2.61版本也可以复现; 把JSON.parseObject(jsonString,Dog.class) 换成com.alibaba.fastjson.JSON.parseObject(jsonString), 转为JSONObject是可以正常输出的, 但是实际需求是需要转为原来的类; 我试了不使用Lomok, 手动为每个类定义get, set方法, 依然可以复现.

9

@Bearin JsonType里面的类名应该是全限定名称,不然fastjson无法确定要加载哪一个类;其次,typeName里面声明的类名应当是实际存在的,不然同样无法加载。我改了一下你的demo,然后可以顺利运营,我的demo会放在附件里,你可以看一看。如果还有问题可以继续提问。 fastjsonIssue2959.zip

5

@OLPMO 如果必须使用类的全限定名的话, 不使用@JSONType注解, 不自定义typeName就可以了, 奇怪的是使用了之后可以序列化, 也会替换@type的value,但是又不能正常反序列化. 请问下, 还有没有办法可以自定义序列化结果@type的value(类全名一般都太长,且如果挪动了类路径位置对已有数据就没办法反序列化), 并且能正常序列化和反序列化的?

1

typeName的作用是指定反序列化时的类,如果不指定typeName,默认就是序列化时当前类的全限定名。你可以看一下我的demo,如果指定了typeName,他就会用typeName指定的类(指定的类可以和你序列化时的目标类不是同一个类)去反序列化json,所以这个必须要用全限定名,不然fastjson无法知道你想用哪一个类去反序列化json。TypeName的值就是序列化后@type的值。 @Bearin