如何使用Jackson或任何其他api对一组对象进行反序列化?

时间:2015-04-22 20:10:32

标签: java arrays json jackson deserialization

我定义了一个模型,我需要映射jsonArray。模型如下:

@JsonPropertyOrder({
    "Command",
    "Created",
    "Id",
    "Image",
    "Labels",
    "Names",
    "Ports",
    "Status"
})
public class Container {

    @JsonProperty("Command")
    private String Command;

    @JsonProperty("Created")
    private long Created;

    @JsonProperty("Id")
    private String Id;

    @JsonProperty("Image")
    private String Image;

    @JsonProperty("Labels")
    private List<String> Labels;

    @JsonProperty("Names")
    private List<String> Names = new ArrayList<String>();

    @JsonProperty("Ports")
    private List<Port> Ports = new ArrayList<Port>();

    @JsonProperty("Status")
    private String Status;

    //Getters and Setters
}

响应是JSONArray,这是我必须映射到Container Class的内容,如下所示:

[  
  {  
    "Command":"/usr/sbin/sshd -D",
    "Created":1429686533,
    "Id":"c00afc1ae5787282fd92b3dde748d203a83308d18aaa566741bef7624798af10",
    "Image":"jay8798:latest",
    "Labels":{  

    },
    "Names":[  
      "/jay8798"
    ],
    "Ports":[  
      {  
        "IP":"0.0.0.0",
        "PrivatePort":22,
        "PublicPort":32845,
        "Type":"tcp"
      },
      {  
        "IP":"0.0.0.0",
        "PrivatePort":3306,
        "PublicPort":32846,
        "Type":"tcp"
      }
    ],
    "Status":"Up 12 hours"
  },
  {  
    "Command":"/usr/sbin/sshd -D",
    "Created":1429686039,
    "Id":"d70f439231d99889c1a8e96148f13a77cb9b83ecf8c9d4c691ddefa40286c04c",
    "Image":"jay898:latest",
    "Labels":{  

    },
    "Names":[  
      "/jay898"
    ],
    "Ports":[  
      {  
        "IP":"0.0.0.0",
        "PrivatePort":22,
        "PublicPort":32841,
        "Type":"tcp"
      },
      {  
        "IP":"0.0.0.0",
        "PrivatePort":3306,
        "PublicPort":32842,
        "Type":"tcp"
      }
    ],
    "Status":"Up 12 hours"
  }
]

这是我尝试的但似乎没有任何效果:

Container[] containerList = mapper.readValue(containerResponse, Container[].class);
int totalContainers = containerList.length;

//This will return correct length of the container.
System.out.println("This is the retrived size : " + containerList.length); 

for(Container cont : containerList) {
    // this statement will print 'null'.There is no exception thrown at this point.
    System.out.println("Container Id : "+cont.getId());
}

或者

List<Container> containerList = 
          mapper.readValue(containerResponse, new TypeReference<List<MyClass>>(){});

我跟着Jackson Deserialize并尝试了帖子中提到的所有解决方案。 它无法映射到模型。所有字段都为null,它读取值。没有值被映射到Container类的属性。模型中缺少任何东西或者我是否需要编写客户逻辑来反序列化json?

2 个答案:

答案 0 :(得分:1)

First off, I'm assuming that

"Labels": {
},

should actually be

"Labels": [
],

since you've defined it to be a list of Strings and not an object of it's own.

This code works for me:

Port.java:

public class Port {
    @JsonProperty("IP")
    private String ip;

    @JsonProperty("PrivatePort")
    private int privatePort;

    @JsonProperty("PublicPort")
    private int publicPort;

    @JsonProperty("Type")
    private String type;

    // Getters and setters
}

main():

String json = ... // Your JSON with the above correction
ObjectMapper objectMapper = new ObjectMapper();
List<Container> containers = objectMapper.readValue(json, new TypeReference<List<Container>>() {});
System.out.println(containers.size());
for(Container container : containers) {
    System.out.println("Container Id : " + container.getId());
}

2
Container Id : c00afc1ae5787282fd92b3dde748d203a83308d18aaa566741bef7624798af10
Container Id : d70f439231d99889c1a8e96148f13a77cb9b83ecf8c9d4c691ddefa40286c04c

答案 1 :(得分:1)

I'm surprised you are not getting an exception when trying to deserialize the object. When I run your code locally I get a

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

The reason looking like you are trying to serialize into an Array when it is a JSON object.

"Labels":{  

},

That is a JSON object, so you should change your type to reflect what it is, or change the serialization of that JSON property to be an array. If you just want to change the type in your Container class, you should use a Map:

@JsonProperty("Labels")
private Map<String, Object> Labels;