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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2864370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:51:05  来源:igfitidea点击:

How do I use Google's Gson API to deserialize JSON properly?

javajsonapigsonserialization

提问by FK82

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

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

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

These are the POJOs I created for parsing (I'll leave out the importstatements for brevity's sake):

这些是我为解析而创建的POJOimport为简洁起见,我将省略这些语句):

(1) The representation of the complete JSON object

(1) 完整JSON对象的表示

public class JObjectContainer {

    private List<JObject> jObjects ;

    public JObjectContainer() { }

    //get & set methods

}

(2) The representation of the nested objects:

(2)嵌套对象的表示:

 public class JObject {

    private String id ;
    private List<JNode> jObjects ;

    public JObject() { } 

    //get & set methods

}

(3) The representation of the items:

(3) 项目的表示:

 public class JNode {

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

    public JNode() { }

    //get & set methods

}

Now, creating a Gson instance (FileReaderfor importing the jsonFile),

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

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

I get a NullPointerExceptionwhenever I try to access the parseable object (e.g. through a ListIterator). Gson doeshowever create an object of the class I specified and does notthrow any subsequent errors.

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

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

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

TIA

TIA

采纳答案by BalusC

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 thatsmart :)

那是不可能的。您需要修改您的JSON结构来表示object1object2等作为的项目阵列。现在它们是一个对象的属性,显然不知道它们中有多少个(否则你没有尝试将它映射为 a List)。Gson 很聪明,但没那么聪明 :)

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

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

{ 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).

结合 Java 表示(不一定称为 POJO,而只是 javabean 或模型对象或值对象)。

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

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

and this Gson call

和这个 Gson 电话

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:

更新:需要明确的是,问题在于您的 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 */
  ]
}

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

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

回答by StaxMan

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 Hymanson 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).

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