Retrofit将未知字段作为Map

时间:2015-03-18 15:24:46

标签: android json retrofit

我目前很难通过改造来检索JSON对象。问题是,我事先并不知道这些字段的名称。通常我会将这些字段映射为Map,但是如何命名这个改进对象?

这就是我的JSON对象的样子:

{
    "User{email='john.doe@example.com', id='JDoe'}" : {
        "101" : 1,
        "102" : 2,
        "103" : 3,
        "104" : 2
     },
     "User{email='jane.doe@example.com', id='JDoe01'}" : {
         "101" : 3,
         "102" : 1,
         "103" : 1,
         "104" : 3
     }
}

改装对象的类:

public static class UserSettings{
    public Map<String, Map<String, Integer>> settingsMap;
}

现在我认为发生的事情是,改造试图找到一个名为“设置地图”的对象。但是这个映射是根元素,因此没有名称,因此settingsMap是一个空对象。

感谢您解决此问题的任何帮助!

提前致谢。

1 个答案:

答案 0 :(得分:2)

您必须为UserSettings对象实现自己的反序列化器。如下所示:

首先为用户设置数据创建模型:

public class UserSettings {
        public Map<String, Map<String, Integer>> settingsMap;

    public  UserSettings(){
        settingsMap = new HashMap<>();
    }

    public void add(String key, Map<String, Integer> settingMap){
        settingsMap.put(key, settingMap);
    }
}

在下一步中为您准备API客户端

public interface UserSettingApiClient {

    @GET("/yourEndpoint")
    UserSettings getUserSetting();
}

现在是最重要的一步。您必须创建自己的JsonDeserializer,如下所示:

public class UserDeserializer implements JsonDeserializer<UserSettings> {

    @Override
    public UserSettings deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        UserSettings userSettings = new UserSettings();
        JsonObject jsonObject = (JsonObject) json;
        for (Map.Entry<String, JsonElement> element : jsonObject.entrySet()){
            String key = element.getKey();
            JsonObject obj = jsonObject.getAsJsonObject(key);
            Map<String, Integer> settingMaps = new HashMap<>();
            for (Map.Entry<String, JsonElement> setting : obj.entrySet()){
                String settingKey = setting.getKey();
                Integer integer = obj.get(settingKey).getAsInt();
                settingMaps.put(settingKey, integer);
            }
            userSettings.add(key,settingMaps);
        }
        return userSettings;
    }
}

执行此操作时,您必须在GsonConverter中注册此反序列化程序。以下示例显示了如何调用完整请求,但您必须在创建RestAdapter

的位置使用此解决方案
new RestAdapter.Builder()
       .setEndpoint("http://your.apiaddress.com")
       .setLogLevel(RestAdapter.LogLevel.FULL)//this is not necessary 
       .setConverter(
              new GsonConverter(
                   new GsonBuilder()
                             .registerTypeAdapter(UserSettings.class, new UserDeserializer())
                   .create()))
      .build()
      .create(UserSettingApiClient.class)
      .getUserSetting();