【问题标题】:Deserialization of generic collections with Gson使用 Gson 反序列化通用集合
【发布时间】:2011-09-18 04:13:03
【问题描述】:

我在使用 GSon 进行 json 反序列化时遇到了一些困难,希望有人能帮助我。

我想反序列化下面的json sn-p:

{
    "fieldA": "valueA",
    "myCollection": {
        "AnotherClass": [
            {
                "objectAfieldA": "valueB",
                "objectAfieldB": "valueC"
            },
            {
                "objectAfieldA": "valueD",
                "objectAfieldB": "valueE"
            }
        ]
    }
}

对应的整体类有以下字段:

...
String fieldA;
List<AnotherClass> = new ArrayList<AnotherClass>();
....

现在,我的问题是,当我使用 fromJson(jsonSample, resultContainer.class) 反序列化时,没有 List&lt;T&gt; 元素,一切都很好,但是当我包含包含的列表时,我得到了 NullPointerException。我已经阅读过如何处理泛型类型的集合以及TypeToken 的使用,但是当我的集合是另一个类的一部分时,我无法应用这些知识……

我真的很感激任何帮助来解决这个问题。

【问题讨论】:

标签: java json gson


【解决方案1】:

对未命名的 JSON 数组进行去实化的解决方案非常简单:

List<resultContainer> lres = gson.fromJson(new FileReader("input.json"), new TypeToken<List<resultContainer>>(){}.getType());

【讨论】:

    【解决方案2】:

    反序列化时,如果要反序列化的最外层结构是泛型集合,则只需要使用TypeToken。原始问题中的示例并非如此。因此,没有必要使用TypeToken

    问题似乎是 JSON 结构与尝试绑定的 Java 结构不匹配。

    JSON 结构定义

    an object with two elements
        element 1 is a string named "fieldA",
        element 2 is an object named "myCollection", which has one element
            the one element is an array named "AnotherClass", composed of objects with two elements
                element 1 is a string named "objectAfieldA",
                element 2 is a string named "objectAfieldB"
    

    因此,定义一个与之匹配的 Java 数据结构,反序列化将非常简单,无需任何自定义处理。如果没有提供这种匹配的 Java 结构,则需要自定义反序列化。

    这是一个使用原始问题中的名称和类型的工作示例。

    import java.io.FileReader;
    
    import com.google.gson.Gson;
    
    public class Foo
    {
      public static void main(String[] args) throws Exception
      {
        Gson gson = new Gson();
        resultContainer result = gson.fromJson(new FileReader("input.json"), resultContainer.class);
        System.out.println(gson.toJson(result));
      }
    }
    
    class resultContainer
    {
      String fieldA;
      MyCollectionContainer myCollection;
    }
    
    class MyCollectionContainer
    {
      SomeOtherClass[] AnotherClass;
    }
    
    class SomeOtherClass
    {
      String objectAfieldA;
      String objectAfieldB;
    }
    

    【讨论】:

    • 很好的答案,恰到好处!我调整了我的 java 结构,我又高兴了。谢谢,布鲁斯。
    • 现在又出现了另一个问题...我使用的服务有时可能只在 AnotherClass 元素内携带一个项目,在这种情况下,它不会被编码为 json 数组(完美地转换为 SomeOtherClass[] ),但只是一个普通的 SomeOtherClass 类型 - 留下数组括号。这打破了我的反序列化。如果我手动添加括号,它会再次解析。这是 JSON 标准吗,你们有解决方法吗?
    • 您所描述的是一个经常发生的问题。也许有些人认为,如果他们生成的 JSON 是有效的,那就足够了,即使它的结构不一致。不幸的是,Gson 还没有一个简单的配置可以用来处理这个经常发生的问题。自定义反序列化处理是必要的。我在stackoverflow.com/questions/6223023 发布了这样一个例子来回答这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    • 2011-12-04
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多