Android Gson解析无键映射对象

Android Gson解析无键映射对象,android,json,gson,retrofit2,Android,Json,Gson,Retrofit2,有人能解释一下我如何解析JSON吗 { "5": { "NumPossibleAchievements": "2", "PossibleScore": "15", "NumAchieved": 0, "ScoreAchieved": 0, "NumAchievedHardcore": 0, "ScoreAchievedHardcore": 0 }, "1838": { "NumPossibleAchievements": "48",

有人能解释一下我如何解析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
}
}
现在我有了一个类,我想用它来做响应

public class UserProgress {

private Map<String, Progress> userProgress;

public Map<String, Progress> getUserProgress() {
    return userProgress;
}
}
和自定义反序列化程序,该程序应将此类型的JSON解析为普通对象。这个反序列化我添加到改装转换器

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;
}
}
公共类UserProgressDeserializer实现JsonDeserializer{
@凌驾
public UserProgress反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{
final JsonObject JsonObject=json.getAsJsonObject();
最终映射参数=readParametersMap(jsonObject);
最终用户进度结果=新用户进度();
if(参数!=null)result.setUserProgress(参数);
返回结果;
}
@可空
私有映射readParametersMap(@NonNull final JsonObject JsonObject){
最终的JsonElement参数=jsonObject.getAsJsonObject();
if(paramsElement==null)返回null;
最终JsonObject参数sobject=paramsElement.getAsJsonObject();
最终映射参数=new HashMap();
对于(Map.Entry:parametersObject.entrySet()){
String key=entry.getKey();
进度值=new Gson().fromJson(entry.getValue().getAsString(),Progress.class);
参数。put(键、值);
}
返回参数;
}
}
还有我的要求

@GET("API_GetUserProgress.php")
Flowable<UserProgress> getUserProgress(@Query("u") @NonNull String userName,
                                                     @Query("i") String gamesCSV);
@GET(“API\u GetUserProgress.php”)
可流动的getUserProgress(@Query(“u”)@非空字符串用户名,
@查询(“i”)字符串(SCSV);
请求工作,在原始体中我看到JSON,但对象包含空映射。我使用断点进行了测试,但它从未进入反序列化程序。现在我的想法是创建一个自定义函数,该函数将解析来自响应原始体的JSON字符串,但这将是spike

感谢您的帮助

UPD: 似乎GSON接受了开箱即用的对象的Map,并将这些对象强制转换为LinkedTreeMap。所以,我们只需要更改请求返回类型

Flowable<Map<String, Progress>> getUserProgress(@Query("u") @NonNull String userName,
                                                @Query("i") String gamesCSV);
可流动的getUserProgress(@Query(“u”)@非空字符串用户名,
@查询(“i”)字符串(SCSV);
冗余

我没有成功使用自定义反序列化程序,所以我实现了一个新函数,该函数从原始响应接受JSON字符串,并将结果映射到所需对象的列表。现在看起来像

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;
    });
Flowable-Flowable=USERS\u API.getUserProgress(用户名,gameidscv);
返回manageRequestWithMapper(可流动,响应库->{
String body=responseBody.String();
JSONObject yourJSON=新的JSONObject(body);
迭代器keysIterator=yourJSON.keys();
List templast=new ArrayList();
while(keysIterator.hasNext()){
String key=keysIterator.next();
JSONObject actualObj=(JSONObject)yourJSON.get(key);
add((new Gson()).fromJson(actualObj.toString(),Progress.class));
}
返回圣殿骑士;
});
UPD: 似乎GSON接受了开箱即用的对象的Map,并将这些对象强制转换为LinkedTreeMap。所以,我们只需要更改请求返回类型

Flowable<Map<String, Progress>> getUserProgress(@Query("u") @NonNull String userName,
                                                @Query("i") String gamesCSV);
可流动的getUserProgress(@Query(“u”)@非空字符串用户名,
@查询(“i”)字符串(SCSV);
冗余

我没有成功使用自定义反序列化程序,所以我实现了一个新函数,该函数从原始响应接受JSON字符串,并将结果映射到所需对象的列表。现在看起来像

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;
    });
Flowable-Flowable=USERS\u API.getUserProgress(用户名,gameidscv);
返回manageRequestWithMapper(可流动,响应库->{
String body=responseBody.String();
JSONObject yourJSON=新的JSONObject(body);
迭代器keysIterator=yourJSON.keys();
List templast=new ArrayList();
while(keysIterator.hasNext()){
String key=keysIterator.next();
JSONObject actualObj=(JSONObject)yourJSON.get(key);
add((new Gson()).fromJson(actualObj.toString(),Progress.class));
}
返回圣殿骑士;
});

您不使用的原因是什么?您不使用的原因是什么?