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

发布于 2024-09-01 18:09:48 字数 1302 浏览 5 评论 0原文

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

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

这些是我为解析创建的 POJO(我将省略 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 for导入 jsonFile),

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

每当我尝试访问可解析对象(例如通过 ListIterator)时,我都会收到 NullPointerException 。然而,Gson 确实创建了我指定的类的对象,并且不会抛出任何后续错误。

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

TIA

In short, this is a sketch of the JSON object I want to parse in JAVA:

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

These are the POJO s I created for parsing (I'll leave out the import statements for brevity's sake):

(1) The representation of the complete JSON object

public class JObjectContainer {

    private List<JObject> jObjects ;

    public JObjectContainer() { }

    //get & set methods

}

(2) The representation of the nested objects:

 public class JObject {

    private String id ;
    private List<JNode> jObjects ;

    public JObject() { } 

    //get & set methods

}

(3) The representation of the items:

 public class JNode {

    private JsonElement item1 ;
    private JsonElement item2 ;
    //<> more item fields

    public JNode() { }

    //get & set methods

}

Now, creating a Gson instance (FileReader for importing the jsonFile),

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

I get a NullPointerException whenever I try to access the parseable object (e.g. through a ListIterator). Gson does however create an object of the class I specified and does not throw any subsequent errors.

I know that this has been done before. So, what am I missing?

TIA

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原谅过去的我 2024-09-08 18:09:48

那是不可能的。您需要修改 JSON 结构以将 object1object2 等表示为数组 的项目。现在它们是一个对象的属性,显然不知道其中有多少个(否则您不会尝试将其映射为 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,因为它无效。

That's not possible. You need to modify your JSON structure to represent object1, object2, etc as items of an array. Right now they are properties of an object of which it's apparently unknown how many of them will be (else you didn't attempt to map it as a List). Gson is smart, but not that smart :)

So, as a basic example, this JSON structure with an array:

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

in combination with the Java representation (which is not necessarily to be called POJO, but just javabean or model object or value object).

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

public class Node {
    private String item1;
    private String item2;
    // +getters.
}

and this Gson call

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

should work.

Update: to be clear, your JSON structure is the problem, not your Java object structure. Assuming that your Java object structure is exactly what you would like to end up with, then your JSON structure should look like follows to get Gson to do its job:

{ 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 */
  ]
}

Only the JsonElement property should be replaced by String, since it's invalid.

末が日狂欢 2024-09-08 18:09:48

我认为 BalusC 对于 GSon 的具体问题给出了很好的指导(一般来说,一对一的数据绑定);但万一您认为应该有更多的动态处理,您也可以考虑其他 JSON 处理包。许多包都有额外的或替代的方式来映射事物:Json-lib、flexjson 和 Jackson 与 Gson 相比至少有一些补充。有些提供更宽松的映射(您将事物的名称定义为类型),其他则实际支持多态类型(声明一个对象,但实际上可以映射到序列化的子类型)。

I think BalusC gave good pointers for the specific question wrt GSon (and in general, one-to-one data binding); but just in case you think there should be more dynamic handling, you could also consider other JSON processing packages. Many packages have additional or alternative ways to map things: Json-lib, flexjson and Jackson at least have additions compared to Gson. Some offer looser mapping (you define names of things to types), others actual support for polymporphic types (declaring an Object but can actually map to subtype that was serialized).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文