【问题标题】:how to identify class by json attribute name using GSON如何使用 GSON 通过 json 属性名称识别类
【发布时间】:2014-10-30 15:00:28
【问题描述】:

我有以下 json:

{
    "list": [
        {
            "BaseClass": {
                "id": 0
            }
        },
        {
            "ExtendedClass1": {
                "id": 1,
                "sum": 100
            }
        },
        {
            "ExtendedClass1_1": {
                "id": 2,
                "sum": 200,
                "expr": "text"
            }
        },
        {
            "ExtendedClass2": {
                "id": 3,
                "total": 300
            }
        }
    ]
}

我还有以下声明继承的类:

MetaClass.java

import java.util.ArrayList;

import com.google.gson.Gson;

public class MetaClass{

    public ArrayList<BaseClass> list = new ArrayList<BaseClass>();

    public static void main(String[] args) {

        String json = "{\"list\":[{\"BaseClass\":{\"id\":0}},{\"ExtendedClass1\":{\"id\":1,\"sum\":100}},{\"ExtendedClass1_1\":{\"id\":2,\"sum\":200,\"expr\":\"text\"}},{\"ExtendedClass2\":{\"id\":3,\"total\":300}}]}";  

        MetaClass gson = new Gson().fromJson(json, MetaClass.class);

        }

 }

BaseClass.java

public class BaseClass{
    public int id;   
    public BaseClass() {   
    }
 }

ExtendedClass1.java

public class ExtendedClass1 extends BaseClass{
    public ExtendedClass1() {
    }
    public int sum;
}

ExtendedClass2.java

public class ExtendedClass2 extends BaseClass {
    public ExtendedClass2() {
    }
    public int total;
}

ExtendedClass1_1.java

public class ExtendedClass1_1 extends ExtendedClass1 {   
    public ExtendedClass1_1() {       
    }
    public String expr;
}

此外,可能有很多此类具有多级继承的类。我试图使这个例子更简单。如何正确解析提到的 json 字符串?请假设我无法更改输入 json,只有我可以更改类并以某种方式编写自定义 fromJson 命令...

编辑:当然,我可以在 BaseClass.java 中添加 json 中可能遇到的所有属性(见下文),但这似乎不是优雅的解决方案。

public ExtendedClass1 ExtendedClass1;
public ExtendedClass2 ExtendedClass2;
public ExtendedClass1_1 ExtendedClass1_1;

【问题讨论】:

  • 别想了,看看 TypeAdaptors
  • user489041,你能更准确地写下答案吗?
  • 以下是关于 SO 使用 TypeAdapters 的类似答案:stackoverflow.com/a/6018852/2543138

标签: java json gson


【解决方案1】:

您可以编写自定义TypeAdapter 并将其注册到 gsonBuilder。在您的自定义类型适配器的read 方法中,您必须管理映射以创建您定义的类的正确实例。我使用了您的列表 json 数组项的标签:

public class CustomTypeAdapter extends TypeAdapter<BaseClass> {

    @Override
    public BaseClass read(JsonReader in) throws IOException {
        BaseClass item = null;

        Gson gson = new Gson();

        JsonParser jsonParser = new JsonParser();
        JsonObject jo = (JsonObject)jsonParser.parse(in);

        JsonElement je = null;
        if ((je = jo.get("BaseClass")) != null) {
            item = gson.fromJson(je, BaseClass.class);
        } else if((je = jo.get("ExtendedClass1")) != null) {
            item = gson.fromJson(je, ExtendedClass1.class);
        } else if((je = jo.get("ExtendedClass1_1")) != null) {
            item = gson.fromJson(je, ExtendedClass1_1.class);
        } else if((je = jo.get("ExtendedClass2")) != null) {
            item = gson.fromJson(je, ExtendedClass2.class);
        }

        return item;
    }

    @Override
    public void write(JsonWriter out, BaseClass item) throws IOException {
        throw new IllegalArgumentException("TypeAdapter.write method not implemented!");
    }
}

测试:

String json = "{\"list\":[{\"BaseClass\":{\"id\":0}},{\"ExtendedClass1\":{\"id\":1,\"sum\":100}},{\"ExtendedClass1_1\":{\"id\":2,\"sum\":200,\"expr\":\"text\"}},{\"ExtendedClass2\":{\"id\":3,\"total\":300}}]}";

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(BaseClass.class, new CustomTypeAdapter());
Gson gson = gsonBuilder.create();

java.lang.reflect.Type listType = new com.google.gson.reflect.TypeToken<List<BaseClass>>() {}.getType();

JsonArray jsonList = (JsonArray) (gson.fromJson(json, JsonObject.class).get("list"));
List<BaseClass> itemList = gson.fromJson(jsonList, listType);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-27
    • 2011-01-23
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    相关资源
    最近更新 更多