代码之家  ›  专栏  ›  技术社区  ›  FK82

如何使用Google的GSONAPI正确反序列化JSON?

  •  22
  • FK82  · 技术社区  · 14 年前

    简而言之,这是我想在Java中解析JSON对象的草图:

    {
        object1: {
                item1: //[String | Array | Object] ,
                item2: // ...
                //<> more items
        object2: { /* .. */ }
        //<> more objects
    }
    

    这些是 波乔 为解析而创建的 import 为了简洁起见:

    (1)完整JSON对象的表示

    public class JObjectContainer {
    
        private List<JObject> jObjects ;
    
        public JObjectContainer() { }
    
        //get & set methods
    
    }
    

    (2)嵌套对象的表示:

     public class JObject {
    
        private String id ;
        private List<JNode> jObjects ;
    
        public JObject() { } 
    
        //get & set methods
    
    }
    

    (3)项目的表示:

     public class JNode {
    
        private JsonElement item1 ;
        private JsonElement item2 ;
        //<> more item fields
    
        public JNode() { }
    
        //get & set methods
    
    }
    

    现在,创建一个GSON实例( FileReader 用于导入 jsonFile )

     Gson gson = new Gson() ;
     JObjectContainer joc = gson.fromJson(jsonFile,JObjectContainer.class) ;
    

    我得到了 NullPointerException 每当我试图访问可解析对象时(例如通过 ListIterator )格森 但是,创建指定的类I的对象,并 引发任何后续错误。

    我知道这是以前做过的。那么,我错过了什么?

    蒂亚

    2 回复  |  直到 13 年前
        1
  •  37
  •   BalusC    14 年前

    那是不可能的。您需要修改JSON结构来表示 object1 , object2 等,作为 数组 . 现在,它们是一个对象的属性,显然不知道其中有多少个(否则,您没有尝试将其映射为 List )GSON很聪明,但不是 那个 聪明的:)

    因此,作为一个基本示例,这个带有数组的JSON结构:

    { nodes:
      [
        { item1: 'value1a', item2: 'value2a' },
        { item1: 'value1b', item2: 'value2b' },
        { item1: 'value1c', item2: 'value2c' }
      ]
    }
    

    与Java表示相结合(它不必被称为POJO,而只是JavaBean或模型对象或值对象)。

    public class Container {
        private List<Node> nodes;
        // +getter.
    }
    
    public class Node {
        private String item1;
        private String item2;
        // +getters.
    }
    

    还有这个GSON电话

    Container container = new Gson().fromJson(json, Container.class);
    

    应该工作。

    更新 要清楚,JSON结构是问题,而不是Java对象结构。假设你的Java对象结构正是你想要的结果,那么你的JSON结构应该像下面这样让Gson做它的工作:

    { jObjects:
      [
        { id: 123, jObjects: 
          [
            { item1: 'value1a', item2: 'value2a' },
            { item1: 'value1b', item2: 'value2b' },
            { item1: 'value1c', item2: 'value2c' }
            /* etc... commaseparated */
          ]
        },
        { id: 456, jObjects: 
          [
            { item1: 'value1d', item2: 'value2d' },
            { item1: 'value1e', item2: 'value2e' },
            { item1: 'value1f', item2: 'value2f' }
            /* etc... commaseparated */
          ]
        }
        /* etc... commaseparated */
      ]
    }
    

    只有 JsonElement 属性应替换为 String 因为它是无效的。

        2
  •  0
  •   StaxMan    14 年前

    我认为Balusc为特定的问题提供了很好的指针(通常是一对一的数据绑定);但是,为了防止您认为应该有更多的动态处理,您还可以考虑其他JSON处理包。许多包都有附加的或可选的映射方法:JSON lib、flexjson和jackson与GSON相比至少有附加的方法。有些提供更宽松的映射(您将事物的名称定义为类型),另一些则实际支持多孔隙类型(声明对象,但实际上可以映射到序列化的子类型)。