GSon属性允许原始或复合映射

时间:2014-11-05 15:58:40

标签: gson

我想从我的模型中创建以下json

我要么

{"name" : "Arsénio", "value" : 12}

{"name" : "Arsénio", "value" : {"min" : 12, "max" : 100, "value" : 200}}

我已经定义了以下POJO&#39>

class Data {
  String name;
  Value value;
}

abstract class Value {}

class IntegerValue : Value { 
int value;
}

class RangeValue : Value {
    int max, min, value;
}

显然,在使用IntegerValue时,不会输出我所需的第一个json的json,因为它会输出

Gson gson = new Gson();

Data data = new Data();
data.name = "Arsénio";
data.value = new IntegerValue();
data.value.value = 12;

String result = gson.toJson(data, Data.class);

System.out.println(result);

输出:

{"name": "Arsénio", "value" : {"value" : 12}}

在这种情况下,建模我的POJO的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

我设法通过使用IntegerValue的类型适配器来解决这个问题,因为我不确定这是否是正确和简单的解决方案,所以我会等待一段时间才能接受我自己的答案。

Gson gson = new GsonBuilder()
                .registerTypeAdapter(IntValue.class, new IntegerValueTypeAdapter())
                .create();
public class IntValueTypeAdapter extends TypeAdapter<IntegerValue> {

@Override
public void write(JsonWriter out, IntegerValue value) throws IOException {
    out.value(value.value);
}


@Override
public IntegerValue read(JsonReader in) throws IOException {
    // do something similar, but the other way around
    throw new UnsupportedOperationException("deserialize not supported for IntegerValue");
}

}

答案 1 :(得分:0)

您可以撰写自定义TypeAdapter

public class ValueTypeAdapter extends TypeAdapter<Value> {

    @Override
    public Value read(JsonReader in) throws IOException {

        Value value = null;

        JsonParser jsonParser = new JsonParser();
        JsonElement je = jsonParser.parse(in);

        if (je instanceof JsonPrimitive) {
            value = new Value();
            value.value = ((JsonPrimitive) je).getAsInt();
        } else if (je instanceof JsonObject) {
            JsonObject jsonObject = (JsonObject) je;
            value = new Value();
            value.max = jsonObject.get("max").getAsInt();
            value.min = jsonObject.get("min").getAsInt();
            value.value = jsonObject.get("value").getAsInt();
        }

        return value;
    }

    @Override
    public void write(JsonWriter out, Value value) throws IOException {
        if (value != null) {
            if (value.min == 0 && value.max == 0) {
                out.value(value.value);
            } else {
                out.beginObject();

                out.name("min").value(value.min);
                out.name("max").value(value.max);
                out.name("value").value(value.value);

                out.endObject();
            }
        }
    }
}

您的POJO课程:

public static class Data {
    String name;
    Value value;
}

public static class Value {
    int max, min, value;
}

<强>测试

    String json0 = "{\"name\" : \"Arsénio\", \"value\" : 12}";
    String json1 = "{\"name\" : \"Arsénio\", \"value\" : {\"min\" : 12, \"max\" : 100, \"value\" : 200}}";

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Value.class, new ValueTypeAdapter());
    Gson gson = gsonBuilder.create();

    // 1) Deserialize json to java instances
    Data data0 = gson.fromJson(json0, Data.class);
    Data data1 = gson.fromJson(json1, Data.class);

    // 2) Serialize json to java instances to see your incoming json string equals to seriallize one 
    String serialized0 = gson.toJson(data0);
    String serialized1 = gson.toJson(data1);

    System.out.println("serialized0:" + serialized0);
    System.out.println("serialized1:" + serialized1);