使用 GSON 将变化的字段名映射到 POJO

Use GSON to map changing field name to POJO

我正在编写一个 Android 应用程序,并使用 RetroFit 与 REST API 进行通信。 classes/POJO 的全部我都写了,除了一个。

这里是 Java 具体 class。 这是父class,这是问题的根源。我需要能够将 userNameResponse 变量映射到下面 JSON 中的用户名

public class DiTopicStats {

    private UserNameResponse userNameResponse;

    public UserNameResponse getUserNameResponse() {
        return userNameResponse;
    }

    public void setUserNameResponse(UserNameResponse userNameResponse) {
        this.userNameResponse = userNameResponse;
    }
}

和子 class,只要我可以从上面的父 class:

映射到它就可以了
public class UserNameResponse {

    //Fields
    //Getters and Setters
}

返回的 JSON 包含一个根据响应而变化的字段。该字段是用户名。例如:

{
    "sMessage": "",
    "diStatus": {
        "diTopicWrongAns": {
            //Some fields
        },
        "diOverallStats": {
            //Some more fields
        },
        "diUserStats": {
            "John Smith": { //PROBLEM: This name changes
                //some other fields
            }
        }
    }
}

因此在这种情况下,名称 "John Smith" 具有动态字段名称。实际上,它可以是任何包含字母、数字、-. 的字符串。

我的问题是,使用 RetroFit,我如何创建一个 Java class 让 RetroFit 将字段映射到变量?

我知道您可以指定 SerialisedName,但这可以在运行时以编程方式完成吗,因为我将在这个阶段拥有 name 或用户。

谢谢。

创建一个名为 DiUserStats 的 pojo,然后定义一个自定义 GsonTypeAdapter,例如

public class DiUserStatsTypeAdapter implements JsonDeserializer<DiUserStats>, JsonSerializer<DiUserStats> {

    @Override
    public DiUserStats deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        DiUserStats target = new DiUserStats();
        JsonObject jsonObject = json.getAsJsonObject();
        Map.Entry<String,JsonElement> object =(Map.Entry<String,JsonElement>)jsonObject.entrySet().toArray()[0];
        target.setName(object.getKey());
        JsonObject targetValues = object.getValue().getAsJsonObject();
        /*parse values to your DiUserStats as documented using targetValues.get("fooProperty").getAsString(), etc */
        return target;
    }

    @Override
    public JsonElement serialize(DiUserStats src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject obj = new JsonObject();
        JsonObject values = new JsonObject();
        values.addProperty("foo", src.getFoo);
        obj.addProperty(target.getName(), values);
        return obj;
    }

} 

然后当您设置 Gson 时使用构建器并添加您的自定义类型适配器,例如

Gson gson = new GsonBuilder().registerTypeAdapter(DiUserStats.class, new DiUserStatsTypeAdapter()).create();