fastjson2 icon indicating copy to clipboard operation
fastjson2 copied to clipboard

[BUG] Deserialization with SupportAutoType

Open Cooperzzy opened this issue 1 year ago • 1 comments

问题描述

Fastjson使用SupportAutoType反序列化属性缺失,考虑到autotype的历史,不确定是否为bug。

环境信息

  • OS信息: [MacOS 12.7.4 M1 Pro 16 GB]
  • JDK信息: [Openjdk 17.0.6]
  • 版本信息:[Fastjson 2.0.49]

重现步骤

Fastjson2:

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.annotation.JSONType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;

public class MutatedIssue1769_fj2 {
    static BirtneyModel sourceModel = new BirtneyModel();

    @BeforeAll
    public static void setUp() {
        AlimeFromConfig alimeFromConfig = new AlimeFromConfig();
        alimeFromConfig.setDefaultFromId("birtney");

        List<AbstractConfig> sourceConfigs = new ArrayList<>();
        sourceConfigs.add(alimeFromConfig);
        Map<String, List<AbstractConfig>> configMap = new HashMap<>();
        configMap.put("FROM", sourceConfigs);

        sourceModel.setConfigs(configMap);
    }

    @Test
    public void testOnInvokeJsonGenericParse2() {

        String json = JSON.toJSONString(sourceModel, JSONWriter.Feature.WriteClassName);
        System.out.println(json);

        BirtneyModel birtneyModel =
                JSONObject.parseObject(json, BirtneyModel.class, JSONReader.Feature.SupportAutoType);

        System.out.println(birtneyModel);
        assertEquals(
                AlimeFromConfig.class,
                birtneyModel.configs.get("FROM").get(0).getClass()
        );
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class AlimeFromConfig
            extends AbstractConfig {
        private String defaultFromId;
        private Map<String, String> urlMap;
    }

    @JSONType(builder = AlimeFromConfig.class)
    public abstract static class AbstractConfig
            implements Serializable {
        private Long id;
        private String type;
        private String subType;
        private String sceneId;
        private Integer version;
    }

    @Data
    public static class BirtneyModel
            implements Serializable {
        private Map<String, List<AbstractConfig>> configs;
    }
}

Fastjson:

import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;

public class MutatedIssue1769_fj {
    static BirtneyModel sourceModel = new BirtneyModel();

    @BeforeAll
    public static void setUp() {
        AlimeFromConfig alimeFromConfig = new AlimeFromConfig();
        alimeFromConfig.setDefaultFromId("birtney");

        List<AbstractConfig> sourceConfigs = new ArrayList<>();
        sourceConfigs.add(alimeFromConfig);
        Map<String, List<AbstractConfig>> configMap = new HashMap<>();
        configMap.put("FROM", sourceConfigs);

        sourceModel.setConfigs(configMap);
    }

    @Test
    public void testOnInvokeJsonGenericParse() {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String json = JSON.toJSONString(sourceModel,  SerializerFeature.WriteClassName);
        System.out.println(json);

        BirtneyModel birtneyModel =
                JSONObject.parseObject(json, BirtneyModel.class, Feature.SupportAutoType);

        System.out.println(birtneyModel);
        assertEquals(
                AlimeFromConfig.class,
                birtneyModel.configs.get("FROM").get(0).getClass()
        );
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class AlimeFromConfig
            extends AbstractConfig {
        private String defaultFromId;
        private Map<String, String> urlMap;
    }

    @JSONType(builder = AlimeFromConfig.class)
    public abstract static class AbstractConfig
            implements Serializable {
        private Long id;
        private String type;
        private String subType;
        private String sceneId;
        private Integer version;
    }

    @Data
    public static class BirtneyModel
            implements Serializable {
        private Map<String, List<AbstractConfig>> configs;
    }
}




期待的正确结果

Fastjson2: MutatedIssue1769_fj2.BirtneyModel(configs={FROM=[MutatedIssue1769_fj2.AlimeFromConfig(defaultFromId=birtney, urlMap=null)]})

Fastjson: MutatedIssue1769_fj.BirtneyModel(configs={})

Cooperzzy avatar May 11 '24 08:05 Cooperzzy

兼容API的SupportAutoType问题不修了

wenshao avatar May 11 '24 12:05 wenshao