在gson对象阅读器中读取不同类型json的向后兼容性

时间:2016-10-12 07:54:42

标签: json gson

我有一个像这样的JSON:

{
  "name": "v19",
  "timestamp" : 1475733360000,
  "type": "long",
  "value": 123
}

新的JSON格式是上面的metrics数组,并且添加了meta_data

{
  "metrics": [
    {
      "name": "v19",
      "timestamp" : 1475733360000,
      "type": "long",
      "value": 123
    }
  ],
  "meta_data": {
    "timestamp" : 1474367139000,
    "count": {
      "app1" : 120
    }
  }
}

使用try-catch是处理这两种JSON的唯一方法吗?或者有更好的方法吗?

现在我的代码如下所示:

switch (reader.peek())
{
    case BEGIN_OBJECT:
        try
        {
            MetaDataMetric metaMetric = parseMetaMetric(reader);
        }
        catch 
        {
            NewMetric metric = parseMetric(reader);
        }
        break;
}

1 个答案:

答案 0 :(得分:0)

最佳方法是对此用例使用“自”“直到”注释。创建Gson对象时,可以设置版本。 API将根据注释 @Since @Until 注释和版本号进行序列化或反序列化。

使用此方法的巨大优势: -

Gson版本可以在应用程序属性文件中维护。如果您具有依赖性,则可以基于要求使用1.0或1.1版本执行代码。任何其他界面,网络服务等。

这是标准最佳做法,支持多个版本的JSON。

Gson gsonv10 = new GsonBuilder().setVersion(1.0).create();
  

@Since - 一个注释,表示自a以来的版本号   成员或类型已经存在。

     

@Until - 一个注释,指示成员或成员之前的版本号   类型应该存在。

JSON to Object: -

public static void main(String[] args) {

        String version10Json = "{\"name\": \"v19\",\"timestamp\" : 1475733360000,\"type\": \"long\",\"value\": 123}";
        String version11Json = "{\"metrics\":[{\"name\":\"v19\",\"timestamp\":1475733360000,\"type\":\"long\",\"value\":123}],\"meta_data\":{\"timestamp\":1474367139000,\"count\":{\"app1\":120}}}"; 

        Gson gsonv10 = new GsonBuilder().setVersion(1.0).create();
        Gson gsonv11 = new GsonBuilder().setVersion(1.1).create();


        System.out.println("Using v11 on v11 JSON ==>" + gsonv11.fromJson(version11Json, MetricRootObject.class));
        System.out.println("Using v10 on v10 JSON ==>" + gsonv10.fromJson(version10Json, MetricRootObject.class));


        System.out.println("Using v10 on v11 JSON ==>" + gsonv10.fromJson(version11Json, MetricRootObject.class));
        System.out.println("Using v11 on v10 JSON ==>" + gsonv11.fromJson(version10Json, MetricRootObject.class));


    }

POJO班级: -

public class MetricRootObject implements Serializable{

    private static final long serialVersionUID = -8304164167299285496L;

    @Until(1.1)
    private String name;

    @Until(1.1)
    private Long timestamp;

    @Until(1.1)
    private String type;

    @Since(1.1)
    private List<Metrics> metrics;

    @Since(1.1)
    @SerializedName("meta_data")
    private MetaData metaData;

    @Until(1.1)
    private Integer value;

    @Override
    public String toString() {
        return "MetricRootObject [name=" + name + ", timestamp=" + timestamp + ", type=" + type + ", metrics=" + metrics
                + ", metaData=" + metaData + ", value=" + value + "]";
    } 


}

public class Metrics implements Serializable{

    private static final long serialVersionUID = -8304164167299285496L;

    @Since(1.1)
    private String name;

    @Since(1.1)
    private Long timestamp;

    @Since(1.1)
    private String type;

    @Since(1.1)
    private Integer value;

    @Override
    public String toString() {
        return "Metrics [name=" + name + ", timestamp=" + timestamp + ", type=" + type + ", value=" + value + "]";
    } 


}

public class MetaData implements Serializable{

    private static final long serialVersionUID = 4332864980951634867L;

    @Since(1.1)
    private Long timestamp;

    @Since(1.1)
    @SerializedName("count")
    private MetricsCount count;

    @Override
    public String toString() {
        return "MetaData [timestamp=" + timestamp + ", count=" + count + "]";
    }
}