使用GSON

时间:2015-11-16 09:00:37

标签: json generics nested gson realm

我正在使用GSON的Retrofit进行JSON序列化,使用Realm进行存储。

我的JSON响应总是看起来像(简称)

{
   status : 1
   data: { object data }
}

所以我有元信息和包含结果(对象或数组)的数据根对象

现在我正在尝试为GSON编写一个自定义反序列化器,它将结果转换为对象或对象列表。

对我来说,它只适用于静态对象类型定义,如:

public class ResponseDeserializer implements JsonDeserializer {

@Override
public Object1 deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
{
    JsonElement data = je.getAsJsonObject().get("data");
    GsonBuilder gsonBuilder = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            });
    Gson gson = gsonBuilder.create();
    Object1 o1 = gson.fromJson(data, new TypeToken<Object1>() {}.getType());
    return o1;
}
}

第一个问题:当我尝试从Json更改为泛型类型时,会产生&#34; com.google.gson.internal.LinkedTreeMap&#34;使用对象的键值对,代码:

public class ResponseDeserializer<T> implements JsonDeserializer<T> {

@Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
{
    JsonElement data = je.getAsJsonObject().get("data");
    GsonBuilder gsonBuilder = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            });
    Gson gson = gsonBuilder.create();
    T o = gson.fromJson(data, new TypeToken<T>() {}.getType());
    return o;
}
}

第二个问题:反序列化器如何根据json结果返回一个对象或一个对象列表。

1 个答案:

答案 0 :(得分:2)

现在我用不同的方法解决了它:

列表和对象的2个响应模型:

public class ApiResponse<T> {
    private int success;
    private String[] errors;
    private String[] messages;
    private T data;
}

public class ApiListResponse<T> {
    private int success;
    private String[] errors;
    private String[] messages;
    private List<T> data;
}

响应模型的1个解串器

public class ResponseDeserializer<T> implements JsonDeserializer {
@Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
    JsonElement data = je.getAsJsonObject().get("data");
    GsonBuilder gsonBuilder = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            });
    Gson gson = gsonBuilder.create();
    T response = gson.fromJson(je, type);
    return response;
}
}

现在我可以为GSON注册类型:

gsonBuilder.registerTypeAdapter(new TypeToken<ApiResponse<Object1>>() {}.getType(), new ResponseDeserializer<ApiResponse>());
gsonBuilder.registerTypeAdapter(new TypeToken<ApiListResponse<Object1>>() {}.getType(), new ResponseDeserializer<ApiListResponse>());

现在可以正确转换以下JSON响应:

ApiResponse

{  
   "data":{  
      "Object1Id":"1",
      "Name":"Test 1",
   },
   "messages":[  
   ],
   "errors":[  
   ],
   "success":"1"
}

ApiListResponse

{  
   "data":[{  
      "Object1Id":"1",
      "Name":"Test 1",
   },{  
      "Object1Id":"2",
      "Name":"Test 2",
   }],
   "messages":[  
   ],
   "errors":[  
   ],
   "success":"1"
}

有更好的解决方案吗?