java泛型 序列化,java – 使用泛型类型和通用字段名称的GSON反序列化

假设我们有这样的结构:

{

"body": {

"cats": [

{

"cat": {

"id": 1,

"title": "cat1"

}

},

{

"cat": {

"id": 2,

"title": "cat2"

}

}

]

}

}

和相应的POJO:

Response.class

私人最终身体;

Body.class

私人最终收藏< CatWrapper>猫

CatWrapper.class

私人决赛猫猫

Cat.class

private final int id;

private final String title;

但是,现在我们说我们有相同的结构,但我们收到卡车而不是Cat

{

"body": {

"trucks": [

{

"truck": {

"id": 1,

"engine": "big",

"wheels": 12

}

},

{

"truck": {

"id": 2,

"engine": "super big",

"wheels": 128

}

}

]

}

}

我在Android上使用GSON(默认的Retrofit json解析器),在给出解决方案的同时考虑这一点.

我们可以在这里使用泛型,所以响应看起来像:

private final Body< ListResponse< ItemWrapper< T>>但我们不能,因为字段名称是特定于类.

题:

如果不创建如此多的样板类,我可以自动序列化它吗?我真的不需要像BodyCat,BodyTruck,BodyAnyOtherClassInThisStructure这样的单独的类,我正在寻找避免使用它们的方法.

@编辑:

由于继承混乱,我改变了类(猫,狗 – >猫,卡车),这里使用的类作为示例不要互相扩展

解决方法:

一个想法是定义一个自定义通用解串器.它的泛型类型将表示包含在Body实例中的列表元素的具体类.

假设以下类:

class Body {

private List list;

public Body(List list) {

this.list = list;

}

}

class Cat {

private int id;

private String title;

...

}

class Truck {

private int id;

private String engine;

private int wheels;

...

}

反序列化器假定json的结构总是相同的,因为您有一个包含名为“body”的对象的对象.此外,它假定此正文的第一个键值对中的值是一个列表.

现在,对于json数组中的每个元素,我们需要再次获取与每个键关联的内部对象.我们反序列化该值并将其放入列表中.

class CustomJsonDeserializer implements JsonDeserializer> {

private final Class clazz;

public CustomJsonDeserializer(Class clazz) {

this.clazz = clazz;

}

@Override

public Body deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

JsonObject body = json.getAsJsonObject().getAsJsonObject("body");

JsonArray arr = body.entrySet().iterator().next().getValue().getAsJsonArray();

List list = new ArrayList<>();

for(JsonElement element : arr) {

JsonElement innerElement = element.getAsJsonObject().entrySet().iterator().next().getValue();

list.add(context.deserialize(innerElement, clazz));

}

return new Body<>(list);

}

}

对于最后一步,您只需要创建相应的类型,实例化并在解析器中注册适配器.例如卡车:

Type truckType = new TypeToken

>(){}.getType();

Gson gson = new GsonBuilder()

.registerTypeAdapter(truckType, new CustomJsonDeserializer<>(Truck.class))

.create();

Body body = gson.fromJson(new FileReader("file.json"), truckType);

如果要删除Body类,甚至可以直接从适配器返回列表.

使用卡车,你将得到[1_big_12,2_super big_128]作为输出,[1_cat1,2_cat2]作为输出.

标签:android,java,json,gson,generics

来源: https://codeday.me/bug/20191001/1839192.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值