/ / Gson analyzuje objekt mapy bez kľúča - android, json, gson, retrofit2

Gson analyzovať objekt bez kľúča - android, json, gson, retrofit2

môže mi niekto vysvetliť, ako môžem analyzovať JSON

{
"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
}
}

Teraz som v triede, ktorú chcem použiť ako odpoveď

public class UserProgress {

private Map<String, Progress> userProgress;

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

Trieda, ktorá predstavuje vnútorný objekt v tejto mape

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;

.....

A vlastný deserializér, ktorý by mal analyzovať tento typ JSON na normálny objekt. Tento deserializátor som pridal do doplnkového konvertora.

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;
}
}

A moja žiadosť

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

Žiadam prácu, v surovom tele vidím, že JSON, aleobjekt obsahuje prázdnu mapu. Testoval som s bodmi prerušenia, ale nikdy sa nedostane do dezerializátora. Moja myšlienka je teraz vytvoriť vlastnú funkciu, ktorá bude analyzovať reťazec JSON zo surového tela odpovede, ale toto bude špička.

Ďakujeme za pomoc

odpovede:

0 pre odpoveď č. 1

UPD: Vyzerá to, že spoločnosť GSON prijíma mapa pre predmety z krabice a obsadiť tieto objekty LinkedTreeMap, Všetko, čo sme potrebovali, bolo zmeniť typ vrátenia žiadosti.

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

neplatný

S vlastným deserializátorom som nemal úspech, a preto som implementoval novú funkciu, z ktorej sa prijíma reťazec JSON prvotná odpoveď, mapy vedú k zoznamu požadovaných objektov. A teraz to vyzerá

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;
});