将“解包的” Json数组反序列化为POJO

时间:2019-06-07 17:07:10

标签: jackson deserialization

我的问题的一半是不知道搜索答案的确切术语。我相信我正在使用基础“成员”节点处理所谓的“扁平”或“未包装” json数组,因为如果每个成员都有一个“ member:”元素,这将起作用“成员”基础属性节点,但没有。

我收到如下所示的json(我无法控制格式):

{

  "id" : "1",

  "context" :

  {

    "id" : "123,

    "title" : "My Title"

  },

  "members": [

    {

      "prop1" : { },

      "prop2" : "123",

      "propArray1" : [ "Value1", "Value2" ],

      "prop3" : "xyz",

      "prop4" : "123"

    },

    {

      "prop1" : { },

      "prop2" : "456",

      "propArray1" : [ "Value1", "Value2" ],

      "prop3" : "abc",

      "prop4" : "456"

    }

  ] }

我的POJO(减去简单的获取/设置):


@JsonAutoDetect
public class MyPojo {

    @JsonProperty
    private String id;
    @JsonProperty
    private Context context;
    @JsonProperty("members")
    private List<Member> members = new ArrayList<>();

    @JsonAutoDetect
    public class Context {
        public Context() {}

        @JsonProperty
        private String id;
        @JsonProperty
        private String title;
    }

    @JsonAutoDetect
    public class Member {

        public Member() {}

        @JsonProperty
        private String prop1;
        @JsonProperty
        private String prop2;
        @JsonProperty
        private List<String> propArray1 = new ArrayList<>();
        @JsonProperty
        private String prop3;
        @JsonProperty
        private String prop4;
        @JsonProperty
        private String prop5;

    }

    public List<Member> getMembers() {
        return members;
    }

    public void setMembers(List<Member> members) {
        this.members = members;
    }
}

我已经尝试过GSON:

new Gson().fromJson(jsonEntity, MyPojo.class);

returns:
java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT

我已经尝试过杰克逊:

new ObjectMapper().readValue(jsonEntity, MyPojo.class);

throws:
org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class MyPojo$Member]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: java.io.StringReader@5c6e5b53; line: 10, column: 3] (through reference chain: MyPojo["members"])

我认为“添加/启用”类型信息不是相关警告,并且确实具有默认构造函数。

我搜索了几十个json反序列化帖子,这个帖子看起来与此类似,但是我必须获取整个Json对象而不仅仅是其中的一部分...而我尝试了它只是提取成员数组而没有工作。

Cannot deserialize JSON to POJO

1 个答案:

答案 0 :(得分:0)

这里有一些问题:

JSON测试数据无效(第二个ID缺少关闭“)。更正的版本:

{
  "id" : "1",
  "context" :
{
  "id" : "123",
  "title" : "My Title"
},
"members": [
{
  "prop1" : { },
  "prop2" : "123",
  "propArray1" : [ "Value1", "Value2" ],
  "prop3" : "xyz",
  "prop4" : "123"
},
{
  "prop1" : { },
  "prop2" : "456",
  "propArray1" : [ "Value1", "Value2" ],
  "prop3" : "abc",
  "prop4" : "456"
}
] }

第二个问题:嵌套类默认情况下具有对封闭类的引用。这样的结果是没有封闭类的实例就无法创建它们。杰克逊,我得到了这个例外:

 Cannot construct instance of `foo.MyPojo$Member` (although at least one Creator exists)

通过将嵌套类转换为静态内部类来解决此问题:

 public static class Context {
    ...
 }

第三个问题:映射与JSON不匹配。

Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
...
(through reference chain: foo.MyPojo["members"]->java.util.ArrayList[0]->foo.MyPojo$Member["prop1"])

通过更改映射来解决此问题。例如:

@JsonAutoDetect
public static class Member {

    public Member() {}

    @JsonProperty
    private Map<String, String> prop1;
    ...
}

使用这3种方法可以更改使用Jackson来反序列化JSON的可能性。