用杰克逊编组地图到对象

时间:2014-12-12 14:45:06

标签: java json jackson deserialization

我正在使用Jackson来调用json对Web应用程序的调用,我正在尝试设计一种可以接受许多不同对象的方法。

例如:

我有两个班级结构

{
    name:"Joe",
    surname:"Bloggs"
}

对应于java类Person

{
    address1:"21 Main st",
    city:"Georgetown",
    zip:"12345"
}

对应于java类地址

现在我想进行一个可以这样处理这些类的调用:

 {
      type:"Person",
      data:{
         name:"Joe",
         surname:"Bloggs"
      }
 }

我可以创建一个将上述请求封送到Map的调用,或者我可以创建两个单独的请求,每个请求对应一个对象结构,并将它们直接编组到相应的类中。

是否可以使用杰克逊将上述请求编组到地图上,然后在阅读地图的一部分后 - 例如。 map.get(“type”) - 使用杰克逊来编组一个子对象 - 例如。 map.get(“data”) - 进入相应的java类而不重新转换回json?

1 个答案:

答案 0 :(得分:2)

您可以使用Jackson多态性。这是一个简单的例子:

public class Polymorphism3Main {

    public static void main(String []args) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();

        String json = objectMapper.writeValueAsString(generatePerson());
        System.out.println("json = " + json);
        System.out.println(objectMapper.readValue(json, Request.class));

        json = objectMapper.writeValueAsString(generateAddress());
        System.out.println("json = " + json);
        System.out.println(objectMapper.readValue(json, Request.class));
    }

    private static Person generatePerson() {
        Person result = new Person();
        result.setName("name");
        result.setSurname("surname");
        return result;
    }

    private static Address generateAddress() {
        Address address = new Address();
        address.setAddress1("address 1");
        address.setCity("city");
        address.setZip("324212");
        return address;
    }
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Person.class, name = "person"),
        @JsonSubTypes.Type(value = Address.class, name = "address")
})
interface Request {
}

class Person implements Request {
    private String name;
    private String surname;
}

class Address implements Request {
    private String address1;
    private String city;
    private String zip;
}

该代码将产生稍微不同的json,但它仍然是可变的:

{"person":{"name":"name","surname":"surname"}}
{"address":{"address1":"address 1","city":"city","zip":"324212"}}

如果你想拥有与你发布的完全相同的json格式 - 你需要创建一个包装器对象。

一般情况下,我建议创建两个单独的方法来不同地处理这两个请求。在这种情况下,您的代码将更加干净,您不需要将Person与Address通过Request接口组合在一起。