Reputation: 877
I currently struggle with retrieving an JSON object with retrofit. The problem is, that I don't know the names of the fields in advance. Normally I would map these fields as a Map, but how do I name this retrofit object?
That's how my JSON object looks like:
{
"User{email='[email protected]', id='JDoe'}" : {
"101" : 1,
"102" : 2,
"103" : 3,
"104" : 2
},
"User{email='[email protected]', id='JDoe01'}" : {
"101" : 3,
"102" : 1,
"103" : 1,
"104" : 3
}
}
The class for the retrofit object:
public static class UserSettings{
public Map<String, Map<String, Integer>> settingsMap;
}
Now what I think happens is that retrofit tries to find a object called 'settingsMap'. But this map is the root element and therefore does not have a name, so the settingsMap is a null object.
Any help to solve this problem is appreciated!
Thanks in advance.
Upvotes: 0
Views: 2155
Reputation: 12365
You have to implement your own deserialiser for UserSettings
object. As is shown below:
As first create model for user setting data:
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);
}
}
In the next step prepare API client for you object
public interface UserSettingApiClient {
@GET("/yourEndpoint")
UserSettings getUserSetting();
}
And now is the most important step. You have to create your own JsonDeserializer
as is shown below:
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;
}
}
When you do this you have to register this deserialiser in your GsonConverter
. The example below shows how to call complete request but you have to use this solution in the place where you create 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();
Upvotes: 2