Jackson JSON如何从对象数组反序列化日期

时间:2014-01-27 22:25:24

标签: java arrays json jackson deserialization

我会使用混合对象序列化/反序列化Object-Array。因此,我创建了一个MyList类,并使用strings,int和date-objects填充items-array。 杰克逊的序列化效果很好。 json-string看起来像这样:

{"objects":["string",123,1390859948022]}

但是在反序列化时,json-string日期被解析为整数。所以我创建了一个自己的类MyDate来将日期包装为带有字段名“date”的json对象。新结果是:

{"objects":["string",123,1390859948022,{"date":1390859948022}]}

现在结果是LinkedHashMap。

以下是我的代码示例:

Maven的依赖关系:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.3.0</version>
    </dependency>

MyList.java

public class MyList {
    private Object[] objects;

    public MyList() {
    }

    public MyList(Object[] objects) {
        this.objects = objects;
    }

    // getter and setter
}

MyDate.java:

public class MyDate {
    private Date date;

    public MyDate() {
    }   

    public MyDate(Date date) {
        this.date = date;
    }
    // Getter and Setter
}

序列化-示例:

public static void serializeTest() throws JsonGenerationException, JsonMappingException, IOException{
    ObjectMapper mapper = new ObjectMapper();       
    Object[] objects = {"string", 123, new Date(), new MyDate(new Date())};
    MyList liste = new MyList(objects);
    mapper.writeValue(System.out, liste);
}

反序列化-示例:

public static void deserializeTest() throws JsonParseException,
        JsonMappingException, IOException {
    String input = "{\"objects\":[\"string\",123,1390858928698,{\"date\":1390858928698}]}";

    ObjectMapper mapper = new ObjectMapper();
    MyList list = mapper.readValue(input, MyList.class);
    System.out.println("#list:" + list);
    System.out.println("#list.getObjects:" + list.getObjects());
    for (Object i : list.getObjects()) {
        System.out.println("\t value=" + i + ", type=" + i.getClass());
    }
}

我已经找到了可能的解决方案,但没有任何效果。我希望有人可以帮助我。

非常感谢您的所有答案。在您的帮助下,我可以解决我的问题

我必须将JsonTypeInfo-Annotation添加到我的对象数组中:

public class MyList {
    @JsonTypeInfo(  
        use = JsonTypeInfo.Id.NAME,  
        include = JsonTypeInfo.As.WRAPPER_OBJECT)  
    @JsonSubTypes({  
        @Type(value = Date.class, name = "date")})  
    private Object[] objects;

为了在其他对象数组中解决这个问题,我使用以下行扩展了我的代码:

mapper.enableDefaultTyping(DefaultTyping.JAVA_LANG_OBJECT, As.WRAPPER_OBJECT);

这适用于我和我的具体问题。

3 个答案:

答案 0 :(得分:2)

阅读Polymorphic Deserialization。目前所有你告诉杰克逊的是你希望它反序列化一系列对象。为了使其正常工作,您需要注释MyDate类(或使用Annotation Mixins注释内置Date类),以便Jackson在序列化日期时输出一些额外的类型信息。反序列化时,Jackson将使用该信息来了解JSON对象所代表的类。

答案 1 :(得分:1)

你的问题是杰克逊无法知道JSON字符串或数字应该映射到java.util.Date,如果你说的只是“映射到java.lang.Object”。

但你可以强制使用类型信息来实现这一点;要使用的注释是@JsonTypeInfo,您可以将其添加到字段旁边,如下所示:

@JsonTypeInfo(...)
private Object[] objects;

答案 2 :(得分:0)

关于日期序列化 - 请参阅http://wiki.fasterxml.com/JacksonFAQDateHandling

关于反序列化:您的属性是通用的 - 对象[]。从您当前的JSON中,无法确定应该实例化的Java类型。这就是JSON应该包含关于它的日期元素的其他信息的原因 ... {@type:“date”,“date”:1390859948022} ... 或者像这样: ... {“date”:{@ type:“date”,“value”:1390859948022} ...

你是如何做到的 - 看看“dnault”之前的回答并链接到那里的杰克逊。