简体   繁体   English

Jackson 序列化和反序列化 DateTime From/To W​​CF DateTime

[英]Jackson serialize and Deserialize DateTime From/To WCF DateTime

I use Jackson to serialise and deserialise object.我使用Jackson来序列化和反序列化对象。 I have .NET WCF DateTime JSON format with Time Zone .我有.NET WCF DateTime JSON格式和Time Zone And Jackson can't deserialise JSON to object.并且杰克逊无法将JSON反序列化为对象。 I found some solutions, but is there any Jackson embedded or suggested solution how to do that?我找到了一些解决方案,但是否有任何Jackson嵌入或建议的解决方案如何做到这一点?

Example dates:示例日期:

  • "/Date(12345678989+0000)/" "/日期(12345678989+0000)/"
  • "/Date(12345678989-0000)/" "/日期(12345678989-0000)/"

See also: How to parse .net DateTime received as json string into java's Date object另请参阅: 如何将作为 json 字符串接收的 .net DateTime 解析为 java 的 Date 对象

To handle date time in format generated by .NET 's JavaScriptSerializer in form /Date(number of ticks)/ you need to implement custom deserialiser.要处理由.NETJavaScriptSerializer/Date(number of ticks)/格式生成的格式的日期时间,您需要实现自定义反序列化器。 To understand what are "ticks" lets take a look at documentation :要了解什么是“滴答声”,让我们看一下文档

Date object, represented in JSON as "/Date(number of ticks)/".日期对象,在 JSON 中表示为“/Date(number of ticks)/”。 The number of ticks is a positive or negative long value that indicates the number of ticks (milliseconds) that have elapsed since midnight 01 January, 1970 UTC.刻度数是一个正或负的 long 值,表示自 UTC 时间 1970 年 1 月 1 日午夜以来经过的刻度数(毫秒)。

The maximum supported date value is MaxValue (12/31/9999 11:59:59 PM) and the minimum supported date value is MinValue (1/1/0001 12:00:00 AM).支持的最大日期值为 MaxValue (12/31/9999 11:59:59 PM),支持的最小日期值为 MinValue (1/1/0001 12:00:00 AM)。

I assume, that in your case you have an offset provided as well, like in examples.我假设,在您的情况下,您也提供了一个偏移量,就像在示例中一样。

Using Java 8 Time package and above knowledge we can implement custom deserialiser as below plus example usage:使用Java 8 Time包及以上知识,我们可以实现如下自定义反序列化器以及示例用法:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import java.io.IOException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        String inputJson = "{\"date\":\"/Date(1583001930882+0100)/\"}";

        ObjectMapper mapper = new ObjectMapper();
        Epoch epoch = mapper.readValue(inputJson, Epoch.class);
        System.out.println(epoch.getDate());
    }
}

class Epoch {

    @JsonDeserialize(using = JavaScriptDateDeserializer.class)
    private OffsetDateTime date;

    public OffsetDateTime getDate() {
        return date;
    }

    public void setDate(OffsetDateTime date) {
        this.date = date;
    }
}

class JavaScriptDateDeserializer extends JsonDeserializer<OffsetDateTime> {

    private final Pattern JAVASCRIPT_DATE = Pattern.compile("/Date\\((-?\\d+)([+-]\\d+)\\)/");

    @Override
    public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = p.getValueAsString();
        Matcher matcher = JAVASCRIPT_DATE.matcher(value);
        if (matcher.matches()) {
            String epoch = matcher.group(1);
            String offset = matcher.group(2);

            Instant instant = Instant.ofEpochMilli(Long.parseLong(epoch));

            return OffsetDateTime.ofInstant(instant, ZoneOffset.of(offset));
        }

        return null;
    }
}

Above code prints:上面的代码打印:

2020-02-29T19:45:30.882+01:00

Serialiser could look like below:序列化器可能如下所示:

class JavaScriptDateSerializer extends JsonSerializer<OffsetDateTime> {

    @Override
    public void serialize(OffsetDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        StringBuilder builder = new StringBuilder(32);
        builder.append("/Date(");
        builder.append(value.toInstant().toEpochMilli());
        if (!value.getOffset().equals(ZoneOffset.UTC)) {
            builder.append(value.getOffset().toString());
        }
        builder.append(")/");

        gen.writeString(builder.toString());
    }
}

You need to handle Time Zone properly, if you always send/receive date in UTC you can skip this part.您需要正确处理时区,如果您总是以UTC发送/接收日期,则可以跳过此部分。

See also:也可以看看:

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

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