在解析来自null
的响应之后,我需要避免返回包含Web Service
项的数组,但是我不知道如何配置Gson
来这样做。我打算这样做,因为我不想处理解析后的响应(必须再次循环数组)。
让我向您展示我的意思的基本示例。
给出此POJO
:
public class Item {
@SerializedName("_id")
private String id; // Required field
private String name;
@SerializedName("accept_ads")
private boolean acceptAds;
// Getters and setters
}
并收到来自Web服务的JSON
响应:
[
{"_id": "a01",
"name": "Test1",
"accept_ads": true},
{"name": "Test2"}
]
我创建了这个反序列化器:
public class ItemDeserializer implements JsonDeserializer<Item> {
@Override
public Item deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Item item = null;
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("_id")) {
item = new Item();
item.setId(jsonObject.get("_id").getAsString());
if (jsonObject.has("name")) {
item.setName(jsonObject.get("name").getAsString());
}
if (jsonObject.has("accept_ads")) {
item.setAcceptAds(jsonObject.get("accept_ads").getAsBoolean());
}
}
return item;
}
}
然后,我创建如下的Gson
和Retrofit
实例:
Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new ItemDeserializer()).create();
mRetrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(gson)).build();
不幸的是,返回的ArrayList<Item>
包含一个Item
和一个null
值。
UPATE
感谢@deluxe1 in the comments below,我读了linked SO thread,它本身并不是我想要的,因为它是有关序列化器而不是脱盐器的。但是,该线程中的另一个答案专门针对反序列化器。
很遗憾,我无法使其正常运行。请注意,在这种情况下,关于JSON HTTP正文响应中的JsonElements为空,这并不是我要实现的目标。在我的情况下,JsonElement可能不是null,但是缺少必填字段,最终使它无效(因此为null)。
鉴于上面的示例类,我创建了以下反序列化器:
public class NonNullListDeserializer<T> implements JsonDeserializer<List<T>> {
@Override
public List<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationcontext context) throws JsonParseException {
Gson gson = new GsonBuilder().create();
List<T> items = new ArrayList<>();
for (final JsonElement jsonElement : json.getAsJsonArray() {
T item = gson.fromJson(jsonElement, typeOfT);
if (item != null) {
items.add(item);
}
}
return items;
}
}
当然,我记得在Gson中将其注册为TypeAdapter。
问题是,调用该方法时typeOfT
是java.util.ArrayList<com.example.Item>
(但是为什么?)。结果,T item = gson.fromJson(jsonElement, typeOfT)
行没有被内部类(在本例中为Item)调用,从而导致以下异常:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $
AFAIK,键入擦除后将无法执行以下操作:
T item = gson.fromJson(jsonElement, T.class)
答案 0 :(得分:0)
"SELECT * from issued_books where student_id= :s_id and book_name = :b_name and issue_date between :start_date and :end_date"
需要进行一些修改:
NonNullListDeserializer
现在,您需要按如下所示对class NonNullListDeserializer<T> implements JsonDeserializer<List<T>> {
@Override
public List<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json instanceof JsonArray) {
final JsonArray array = (JsonArray) json;
final int size = array.size();
if (size == 0) {
return Collections.emptyList();
}
final List<T> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
// get element type
Type elementType = $Gson$Types.getCollectionElementType(typeOfT, List.class);
T value = context.deserialize(array.get(i), elementType);
if (value != null) {
list.add(value);
}
}
return list;
}
return Collections.emptyList();
}
}
有效负载进行反序列化:
JSON