如何使用GSON通过json属性名识别类

时间:2014-10-30 15:00:29

标签: java json gson

我跟随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,只有我可以更改类并以某种方式从json命令编写自定义...

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

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

1 个答案:

答案 0 :(得分:0)

您可以编写自定义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);