使用Gson反序列化Map<String, List<?>>

5

我在服务器上序列化数据:

Gson gson = new Gson();
Map<String, List<?>> resultMap = BackendUpdateManager.getInstance()
    .getUpdates(timeHolder, shopIdInt, buyerIdInt);
gson.toJson(resultMap);

以及反序列化:

Gson gson = new Gson();
Map<String, List<?>> resultMap =  gson.fromJson(json,
    new TypeToken<Map<String, List<?>>>() {
    }.getType());

然而,当我尝试使用Map中的项目时:
List<ProductCategory> productCategoryList = (List<ProductCategory>)updateMap.get(key);

for(ProductCategory productCategory : productCategoryList) {

}

我遇到了错误:

由于:java.lang.ClassCastExceptioncom.google.gson.internal.LinkedTreeMap无法转换为com.example.model.entity.ProductCategory

我该如何修复这个错误或以其他方式创建一个具有List<不同类>Map

我尝试创建包含List而非Map<String, List<?>>的不同类的getter和setter,用于序列化和反序列化。但是我正在寻找更好的方法。


如果你知道它是一个 Map<String, List<ProductCategory>>,为什么要将其反序列化为 Map<String, List<?>> - azurefrog
@azurefrog 这不仅仅是List<ProductCategory>。不同的键有不同的类型:updateMap.get(key) - ViT-Vetal-
正如错误所指出的那样:当您使用GSON和JACKSON进行反序列化时,它们会使用某种映射来反序列化字符串,您需要自己进行映射。 - igreenfield
当我尝试在反序列化后使用List<?>中的对象时,会出现错误。这种错误通常是由于错误的反序列化引起的。 https://dev59.com/Nmkv5IYBdhLWcg3wxjvQ - ViT-Vetal-
1个回答

2
Gson应该如何知道特定的Json字符串是一个“ProductCategory”?例如,如果“ProductCategory”的定义如下:
package com.stackoverflow.vitvetal;  

public class ProductCategory {
    String name;
    String type;
}

"而且Json是这样的:"
{
    "name":"bananas",
    "type":"go-go"
}

“告诉Gson创建一个com.stackoverflow.vitvetal.ProductCategory实例的链接在哪里?”
“这个链接不存在,因为你没有告诉Gson。”
“所以Gson会创建一个Map<String,String>,看起来像…”
"name" -> "bananas"
"type" -> "go-go"

如果你想做一些不同的事情,最简单但也最没有效力的方法是在创建你的 TypeToken 时完全指定参数化类型;不允许使用通配符 <?>
如果你需要做更强大的事情,比如创建具有更多对象变体的映射,你需要创建一个自定义反序列化器,使用 TypeAdapter<T>,教导 Gson 如何处理你特定类型的对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接