从服务器返回的 JSON 数据可以返回一个对象,或者如果该对象为空,则返回一个空字符串 ("")。
我的问题是我的 DTO 需要一个对象,但它看到一个字符串并崩溃。
PersonDTO
data class PersonDto(
@SerializedName("firstName") val first: String,
@SerializedName("lastName") val last: String,
@SerializedName("favorites") val favorites: FavoriteDto,
)
FavoriteDto
class FavoriteDto(
@SerializedName("color") val color: String,
@SerializedName("number") val number: Int
)
来自服务器的不同响应
"person" : {
"firstName": "Steve",
"lastName" : "Johnson",
"favorites" : {
"color": "Purple",
"number": 25
}
}
...
"person" : {
"firstName": "Steve",
"lastName" : "Johnson",
"favorites" : ""
}
我听说我可能需要一个自定义的 GSON 反序列化器,但除了开箱即用的东西之外,我从未对 GSON 做过任何事情 - 所以我希望在正确的方向上得到插入。
谢谢!
最佳答案
最简单的技巧是您可以在类中添加具有相同序列化名称但数据类型为 String 的额外字段。像这样 -
data class PersonDto(
@SerializedName("firstName") val first: String,
@SerializedName("lastName") val last: String,
@SerializedName("favorites") val favorites: FavoriteDto,
@SerializedName("favorites") val favoritesStr: String,
)
由于 Gson 中没有任何内容作为“必填”字段,如果 JSON 中缺少某些内容,您只会在反序列化对象中得到一个空值。因此,如果存在空字符串,FavoriteDto 对象将为 null,否则不为 null。
编辑
我正在添加一些我之前编写的 Java 代码。这可能会有所帮助:
public class PersonDto {
private FavoriteDto favorites;
private String favoritesStr;
public FavoriteDto getResponseDataObject() {
return favorites;
}
public void setResponseDataObject(FavoriteDto favorites) {
this.favorites = favorites;
}
public String getResponseDataString() {
return favoritesStr;
}
public void setResponseDataString(String favoritesStr) {
this.favoritesStr = favoritesStr;
}
定义反序列化器:
public static class ArrayObjectDualityDeserializer implements JsonDeserializer<PersonDto> {
public PersonDto deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
PersonDto response = new PersonDto();
JsonObject object = json.getAsJsonObject();
if(object.get("favorites").isJsonArray()) {
} else if(object.get("favorites").isJsonObject()) {
try {
FavoriteDto dtoObject = gson.fromJson(object.get("favorites"), FavoriteDto.class);
response.setResponseDataObject(dtoObject);
} catch (JsonSyntaxException e) {
DebugLogger.e("Error " + e);
}
} else if (object.get("favorites").isJsonNull()) {
} else {
response.setResponseDataString(object.get("favorites").getAsString());
}
}
}
和:
public static Gson gson = new GsonBuilder()
.registerTypeAdapter(PersonDto.class, new ArrayObjectDualityDeserializer())
.create();
最后:
private static Retrofit retrofit = null;
private static OkHttpClient.Builder httpClient = null;
private static OkHttpClient session_client = null;
httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new SessionOkHttpInterceptor());
session_client = httpClient.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(session_client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
关于Android 改造和 GSON : JSON response returns object or string as property value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48120176/