/ / Gson Pars Kartenobjekt ohne Schlüssel - Android, Json, Gson, Retrofit2

Gson Pars Kartenobjekt ohne Schlüssel - Android, Json, Gson, Retrofit2

kann mir jemand erklären, wie ich JSON parsen kann

{
"5": {
"NumPossibleAchievements": "2",
"PossibleScore": "15",
"NumAchieved": 0,
"ScoreAchieved": 0,
"NumAchievedHardcore": 0,
"ScoreAchievedHardcore": 0
},
"1838": {
"NumPossibleAchievements": "48",
"PossibleScore": "400",
"NumAchieved": "48",
"ScoreAchieved": "400",
"NumAchievedHardcore": "48",
"ScoreAchievedHardcore": "400"
},
"7634": {
"NumPossibleAchievements": 0,
"PossibleScore": 0,
"NumAchieved": 0,
"ScoreAchieved": 0,
"NumAchievedHardcore": 0,
"ScoreAchievedHardcore": 0
}
}

Jetzt habe ich eine Klasse, die ich für die Antwort verwenden möchte

public class UserProgress {

private Map<String, Progress> userProgress;

public Map<String, Progress> getUserProgress() {
return userProgress;
}
}

Auch Klasse, die das innere Objekt in dieser Map darstellt

public class Progress {

@SerializedName("NumPossibleAchievements")
private String numPossibleAchievements;
@SerializedName("PossibleScore")
private String possibleScore;
@SerializedName("NumAchieved")
private int numAchieved;
@SerializedName("ScoreAchieved")
private int scoreAchieved;
@SerializedName("NumAchievedHardcore")
private int numAchievedHardcore;
@SerializedName("ScoreAchievedHardcore")
private int scoreAchievedHardcore;

.....

Und benutzerdefinierter Deserializer, der diesen JSON-Typ auf normales Objekt analysieren soll. Dieser Deserializer habe ich zum Retrofit-Konverter hinzugefügt.

public class UserProgressDeserializer implements JsonDeserializer<UserProgress> {

@Override
public UserProgress deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final Map<String, Progress> parameters = readParametersMap(jsonObject);
final UserProgress result = new UserProgress();

if (parameters != null) result.setUserProgress(parameters);
return result;
}

@Nullable
private Map<String, Progress> readParametersMap(@NonNull final JsonObject jsonObject) {
final JsonElement paramsElement = jsonObject.getAsJsonObject();
if (paramsElement == null) return null;

final JsonObject parametersObject = paramsElement.getAsJsonObject();
final Map<String, Progress> parameters = new HashMap<>();
for (Map.Entry<String, JsonElement> entry : parametersObject.entrySet()) {
String key = entry.getKey();
Progress value = new Gson().fromJson(entry.getValue().getAsString(), Progress.class);
parameters.put(key, value);
}
return parameters;
}
}

Und meine Bitte

@GET("API_GetUserProgress.php")
Flowable<UserProgress> getUserProgress(@Query("u") @NonNull String userName,
@Query("i") String gamesCSV);

Arbeit anfragen, im rohen Körper sehe ich das JSON, aberObjekt enthält leere Map. Ich habe mit Breakpoints getestet, aber es geht nie in Deserializer. Jetzt ist meine Idee, benutzerdefinierte Funktion zu erstellen, die JSON-Zeichenfolge von Antwortrohkörper analysieren wird, aber das wird Spitze sein.

Danke für jede Hilfe

Antworten:

0 für die Antwort № 1

UPD: Scheint wie GSON akzeptiert Karte zum Objekte aus der Box und wirf diese Objekte auf LinkedTreeMap. Alles, was wir brauchten, war, den Rückgabetyp der Anfrage zu ändern.

Flowable<Map<String, Progress>> getUserProgress(@Query("u") @NonNull String userName,
@Query("i") String gamesCSV);

REDUNDANT

Ich hatte keinen Erfolg mit benutzerdefinierten Deserializer, also habe ich eine neue Funktion implementiert, die JSON-String von akzeptiert rohe Antwort, Karten führen zur Liste der benötigten Objekte. Und jetzt sieht es so aus

Flowable<ResponseBody> flowable = USERS_API.getUserProgress(userName, gameIDsCSV);
return manageRequestWithMapper(flowable, responseBody -> {
String body = responseBody.string();
JSONObject yourJSON = new JSONObject(body);
Iterator<String> keysIterator = yourJSON.keys();
List<Progress> tempList = new ArrayList<>();
while (keysIterator.hasNext()) {
String key = keysIterator.next();
JSONObject actualObj = (JSONObject) yourJSON.get(key);
tempList.add((new Gson()).fromJson(actualObj.toString(), Progress.class));
}
return tempList;
});