java - Gson 反序列化为 Map 通用类型

标签 java json gson

尝试将 JSON 反序列化为 Map,其中 K 是一个字符串,V 是几种类型之一(即 String int 或 boolean)。使用 Gson,我尝试了以下代码:

public static void main(String[] args) {
JsonObject json = new JsonObject(); 
json.addProperty("str", "str-value");
json.addProperty("int", 10);
json.addProperty("bool", true);
// "json" now contains {"str":"str-value","int":10,"bool":true}
Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(json, mapType);

String str = (String) map.get("str"); // cannot cast Object to String
str = String.valueOf(map.get("str")); // results in java.lang.Object@1632847
}

最佳答案

技术解答

如果你附上Gson源代码,然后调试程序你就会找到问题的根源。问题似乎在于 Gson 代码。

由于您调用 fromJson() 的值是 Object 类型,因此将使用类 com.google.gson.ObjectNavigator 并进入这部分代码 [~第 113 行]

else if (objTypePair.type == Object.class && isPrimitiveOrString(objectToVisit)) {
   visitor.visitPrimitive(objectToVisit); //Target value is the proper value after this call
   visitor.getTarget(); //target value is now a blank Object.

其中 visitor 是 JSonObjectDeserializationVisitor 类型,objectToVisit 是您的值,objectTypePair 是它要成为的类型(对象)。

现在,JsonObjectDeserializationVisitor 有一个名为 constructed 的标志,默认设置为 false。因此,当调用 getTarget() 方法时,它会检查构造的标志是否为真,如果不是,它会创建您尝试创建的对象的新实例。因为永远不会设置构造的标志,所以对 getTarget() 的调用返回一个空白对象。

对 getTarget() 的调用在代码中似乎是不必要的,而且似乎是问题的根源。 visitPrimitive 通过将解析后的值放入将被传回的目标变量中来执行适当的操作。这似乎是一个围绕对象类型的错误。

这不是您可以解决的问题,除非您愿意对 Gson 进行自定义构建。我建议将其作为报告提交到 Gson 论坛上。 已经有 one report filed对于 1.5 版

变通

我看到有两种方法可以在短期内解决这个问题。

1) 制作<String, String>类型的 map ,虽然你丢失了类型,但你仍然可以正确地取回值

2) 首先将值放入一个 bean 类中,然后将其序列化。

public class myObj{
  String myStr;
  int    myInt;
  boolean myBool;
  //get and set methods
}

public static void main(String args[]){
   MyObj o = new MyObj();
   o.setMyStr("str-value");
   Gson gson = new Gson();
   String json = gson.toJson(o);

   o = gson.fromJson(json, MyObj.class);
}

两者都违背了你想要做的事情的目的,但我相信在谷歌法庭上修复这个错误。

关于java - Gson 反序列化为 Map 通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7503375/

相关文章:

java - JAXB重复解析小xml文档

java - Android Volley POST - 正文中的 JSON 编码

c# - 在 C# 中反序列化 JSON 数组

java - 从 JSON 反序列化时,时间会添加到日期中

java - gson 未终止的字符串错误

protocol-buffers - gson vs Protocol Buffer

android - 应用程序崩溃(有时)并出现致命信号 11 (SIGSEGV),代码 1

java - Spring 身份验证,它是否使用加密的 cookie?

java - Java VisualVM 中的总方法时间

java - 获取 "MessageBodyWriter not found for media type=application/json"尝试通过 JAX-RS Web 服务发送 JSON 对象