Начнем с примера:
Если данные верны, это должно быть (Beijing
cities
пусто)
{
"code":200,
"msg":"success",
"data":[
{
"id":1,
"name":"Beijing",
"cities":[]
},
{
"id":2,
"name":"Guangdong",
"cities":[
{
"id":1,
"name":"Guangzhou"
}
]
}
]
}
Теперь я получил неверные данные. (Beijing
cities
равно нулю)
{
"code":200,
"msg":"success",
"data":[
{
"id":1,
"name":"Beijing",
"cities":null
},
{
"id":2,
"name":"Guangdong",
"cities":[
{
"id":1,
"name":"Guangzhou"
}
]
}
]
}
Я использую Retrofit2
ResponseBodyConverter
, класс сущности:
public class Result<T> {
private int code;
private String msg;
private T data;
// getters, setters
}
public class Province {
private int id;
private String name;
private List<City> cities;
}
public class City {
private int id;
private String name;
}
Данные, полученные после десериализации, выглядят так:
но мне нужны следующие данные:
Для лучшей отказоустойчивости, когда данные представлены в списке, я хочу обработать их самостоятельно.
Прежде всего, я попытался использовать JsonDeserializer
Gson gson = new GsonBuilder()
.serializeNulls()
.registerTypeHierarchyAdapter(List.class, new GsonListAdapter())
.create();
static class GsonListAdapter implements JsonDeserializer<List<?>> {
@Override
public List<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
Type itemType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0];
List list = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
JsonElement element = array.get(i);
Object item = context.deserialize(element, itemType);
list.add(item);
}
return list;
} else {
return Collections.EMPTY_LIST;
}
}
}
JsonDeserializer
действительно, если данные ""
, {}
и []
, но data
равно null
, они не будут работать.
Тогда я попытался использовать TypeAdapter
static class GsonListAdapter extends TypeAdapter<List<?>> {
@Override
public void write(JsonWriter out, List<?> value) throws IOException {
out.value(String.valueOf(value));
}
@Override
public List<?> read(JsonReader reader) throws IOException {
if (reader.peek() != JsonToken.BEGIN_ARRAY) {
reader.skipValue();
return Collections.EMPTY_LIST;
}
return new Gson().fromJson(reader, new TypeToken<List<?>>() {}.getType());
}
}
Таким образом, независимо от того, что data
, он может работать должным образом. Мы знаем, что использование TypeToken<List<?>>
даст нам LinkedHashMap
, Так что хотя TypeAdapter
может работать должным образом, но я не знать, как конвертировать JsonReader
в List <?>
.
Так что мне интересно, есть ли другие способы, которыми я могу обработать неправильные данные списка? Или конвертировать JsonReader
в List <?> data
, который я хочу.