使用GSON将更改字段名称映射到POJO

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用GSON将更改字段名称映射到POJO相关的知识,希望对你有一定的参考价值。

我正在编写一个android应用程序,并使用RetroFit与REST API进行通信。我写了所有课程/ POJO,除了一个。

这是特定类的Java。这是父类,它是问题的根源。我需要能够将userNameResponse变量映射到下面的JSON中的用户名

public class DiTopicStats {

    private UserNameResponse userNameResponse;

    public UserNameResponse getUserNameResponse() {
        return userNameResponse;
    }

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

和子类,只要我可以从上面的父类映射到它,它应该没问题:

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,我如何创建一个允许RetroFit将字段映射到变量的Java类?

我知道你可以指定一个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();

以上是关于使用GSON将更改字段名称映射到POJO的主要内容,如果未能解决你的问题,请参考以下文章

Android:将 json 值映射到 pojo

你真的会用Gson吗?Gson使用指南

Gson @SerializedName注解使用说明

如何更改杰克逊以检测 POJO 中的所有字段,而不仅仅是公共字段?

Gson空值映射问题,当实体类字段不全Gson的映射

将 json 字段绑定到 POJO 中具有不同名称的字段的注解