[alibaba/fastjson]FastjsonASMDeserializer_1_Classname.deserialze(unknown source)里面到底发生了什么?

2023-12-11 411 views
2

1.设置safeMode=true, String a={"@type":providerSetting,"Id":1,"config":{"@type":"Config","id":2}}, JSON.parseObject(a,providerSetting.class), 对providerSetting配置autoTypeCheckHandler, 报错为:不支持autoType:Config。如下图 123456 我以为下一步应该调用JavaBeanDeserializer.deserialze(DefaultJSONParser,Type,Object,int)( )方法。 然而他进入到unknown source后调用的是JavaObjectDeserializer.deserialze(DefaultJSONParser,Type,object)( ),其中type=java.lang.object。

2.设置safeMode=true,String a={"@type":providerSetting,"Id":1}, 没有对providerSetting配置autoTypeCheckHandler,可以正常反序列化。 456 进入到这个 not avaliable方法后直接返回了。

!!!所以想问一下,这个unknown source中到底做了什么操作?

回答

4

这个是通过asm库动态生成的类,没有source

8

那是会有什么特殊情况会导致即使设置safeMode=true也会正常反序列化吗?

8

`import static org.junit.Assert.assertEquals;

import java.io.Serializable;

import org.junit.Test;

import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.serializer.SerializerFeature;

public class test2 { @Test public void test_for_checkAutoType() throws Exception { ParserConfig.getGlobalInstance().setSafeMode(true);

    Cat cat0 = new Cat();
    Identity i = new Identity();
    i.id = 222;
    cat0.catId = 111;
    cat0.i = i;
    // cat0_1:不需要@jsontype
    // jsonString为{"@type":"包名.test2$Cat","catId":111,"i":{"id":222}}
    String jsonString = JSON.toJSONString(cat0, SerializerFeature.WriteClassName);
    Cat cat0_1 = (Cat) JSON.parseObject(jsonString, Cat.class);
    assertEquals(222, cat0_1.i.id);

    // cat0_2:需要@jsontype
    Cat cat0_2 = (Cat) JSON.parseObject("{\"@type\":\"Cat\",\"catId\":123,\"i\":{\"@type\":\"Identity\",\"id\":456}}", Cat.class);
    assertEquals(456, cat0_2.i.id);

    // cat1_1:Cat不需要@jsontype,但是NewIdentity会报错,但是在位置 ②加上@jsontype还是会报错
    // jsonString1为{"@type":"包名.test2$NewCat","catId":111,"i":{"@type":"包名.test2$Identity","id":222}}
    // 与cat0_1的区别是对参数i也增加了@type
    NewCat cat1 = new NewCat();
    cat1.catId = 111;
    cat1.i = i;
    String jsonString1 = JSON.toJSONString(cat1, SerializerFeature.WriteClassName);

    NewCat cat1_1 = (NewCat ) JSON.parseObject(jsonString1, NewCat .class);
    //assertEquals(222, cat1_1.i.id);
}

public static class Animal implements Serializable {

}

@JSONType(autoTypeCheckHandler = MyAutoTypeCheckHandler.class) // ①
public static class Cat extends Animal implements Serializable {
    public int catId;
    public Identity i;
}

public static class Mouse extends Animal {

}

public static class NewAnimal implements Serializable {
    public Object i;
}

public static class NewCat extends NewAnimal implements Serializable {
    public int catId;
}

@JSONType(autoTypeCheckHandler = MyAutoTypeCheckHandler.class) // ②
public static class Identity implements java.io.Serializable {
    public int id;
}

public static class MyAutoTypeCheckHandler implements ParserConfig.AutoTypeCheckHandler {

    public Class<?> handler(String typeName, Class<?> expectClass, int features) {
        if ("Cat".equals(typeName)) {
            return Cat.class;
        }

        if ("Mouse".equals(typeName)) {
            return Mouse.class;
        }

        if ("Identity".equals(typeName)) {
            return Identity.class;
        }

        return null;
    }
}

} `

6

您好,关于cat1_1的测试。如果把NewAnimal中的参数从object换成准确的Identity,那么该测试也可以不需要@jsontype正常运行