使用 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();
我正在编写一个 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();