简体   繁体   English

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

[英]Jackson JSON how to deserialize date from object-array

I would serialize/deserialize a Object-Array with mixed objects. 我会使用混合对象序列化/反序列化Object-Array。 Therefor I created a MyList class und fill the items-array with strings, int and date-objects. 因此,我创建了一个MyList类,并使用strings,int和date-objects填充items-array。 Serialization with jackson works well. 杰克逊的序列化效果很好。 The json-string looks like this: json-string看起来像这样:

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

But on deserialize the json-string date is parsed as an integer. 但是在反序列化时,json-string日期被解析为整数。 So I created a own class MyDate to wrap the date as a json-object with fieldname "date". 所以我创建了一个自己的类MyDate来将日期包装为带有字段名“date”的json对象。 The new result was: 新结果是:

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

Now the result is a LinkedHashMap. 现在结果是LinkedHashMap。

Here are my code-samples: 这是我的代码示例:

Maven-Dependencies: 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 MyList.java

public class MyList {
    private Object[] objects;

    public MyList() {
    }

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

    // getter and setter
}

MyDate.java: MyDate.java:

public class MyDate {
    private Date date;

    public MyDate() {
    }   

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

Serialize-Example: 序列化-实施例:

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);
}

Deserialize-Example: 反序列化-实施例:

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());
    }
}

I have search for a possible solution, but nothing worked. 我已经找到了可能的解决方案,但没有任何效果。 I hope someone can help me. 我希望有一个人可以帮助我。

Thanks a lot for all your answers. 非常感谢您的所有答案。 With your help I could solve my problem 在你的帮助下,我可以解决我的问题

I had to add JsonTypeInfo-Annotation to my object-array: 我不得不将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;

To solve this problem also in other object-arrays I have extended my code with the following line: 为了解决这个问题,在其他对象数组中,我使用以下行扩展了我的代码:

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

This works for me and my concrete problem. 这适用于我和我的具体问题。

Read up on Polymorphic Deserialization . 阅读多态反序列化 Currently all you're telling Jackson is that you want it to deserialize an array of Objects. 目前所有你告诉杰克逊的是你希望它反序列化一系列对象。 In order for this to work, you need to annotate your MyDate class (or use Annotation Mixins to annotate the built-in Date class) so Jackson will output some additional type info when serializing your date. 为了使其工作,您需要注释MyDate类(或使用Annotation Mixins来注释内置的Date类),因此Jackson在序列化日期时会输出一些额外的类型信息。 When deserializing, Jackson will use the that info to know what kind of class the JSON object represents. 反序列化时,Jackson将使用该信息来了解JSON对象所代表的类。

Your problem is that there is no way for Jackson to know that a JSON String or Number should map to java.util.Date , if all you say is "map to java.lang.Object". 你的问题是杰克逊没有办法知道JSON字符串或数字应该映射到java.util.Date ,如果你说的只是“映射到java.lang.Object”。

But you can force use of type information to make this possible; 但是你可以强制使用类型信息来实现这一点; annotation to use is @JsonTypeInfo , and you can add that next to field like so: 要使用的注释是@JsonTypeInfo ,您可以在字段旁边添加它,如下所示:

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

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

Regarding deserialization: your attribute is generic - Object[]. 关于反序列化:您的属性是通用的 - 对象[]。 From your current JSON it is impossible to determine in what Java type should it be instantiated. 从您当前的JSON中,无法确定应该实例化的Java类型。 That's why JSON should contain additional info about it's date element, kind of ... {@type: "date", "date":1390859948022} ... or like this: ... {"date": {@type: "date", "value": 1390859948022} ... 这就是为什么JSON应该包含关于它的日期元素的其他信息,...... {@type:“date”,“date”:1390859948022} ......或者像这样:... {“date”:{@ type: “date”,“value”:1390859948022} ...

How you do that - see the previous answer from "dnault" and link to Jackson there. 你是怎么做到的 - 看看“dnault”之前的回答并链接到那里的杰克逊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM