2017-07-06 123 views
1

有人可以解释我GSON分析映射对象,我怎么能解析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; 
} 
} 

类也代表内部类对象在这张地图中

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; 

..... 

而自定义的反序列化器应该解析这个类型的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; 
} 
} 

,我有所求

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

申请工作,在生的身体我看到JSON,但对象包含空映射。我测试了断点,但它永远不会进入解串器。现在我的想法是创建自定义函数,它将解析来自响应原始主体的JSON字符串,但这将会出现尖峰。

感谢所有帮助

+0

有没有你不使用[GSON转换器]任何原因(https://github.com/square/retrofit/tree/master/retrofit-converters/gson)? – SpaceBison

回答

0

UPD: 好像GSON接受对象开箱地图投下这些对象LinkedTreeMap。所以,我们需要的只是改变请求返回类型。

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

冗余

我曾与定制解串器没有成功,所以我实现了一个接受原始响应 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; 
    });