Джексон сериализует и десериализует DateTime с / на WCF DateTime - PullRequest
1 голос
/ 28 февраля 2020

Я использую Jackson для сериализации и десериализации объекта. У меня есть .NET WCF DateTime JSON формат с Time Zone. И Джексон не может десериализовать JSON до объекта. Я нашел некоторые решения, но есть ли Jackson встроенное или предлагаемое решение, как это сделать?

Пример даты:

  • "/ Дата (12345678989 + 0000) /"
  • "/ Date (12345678989-0000) /"

См. Также: Как выполнить синтаксический анализ. net DateTime, полученный как json строка в объекте Date Java

1 Ответ

1 голос
/ 29 февраля 2020

Для обработки даты и времени в формате, сгенерированном .NET * JavaScriptSerializer в форме /Date(number of ticks)/, вам необходимо реализовать собственный десериализатор. Чтобы понять, что такое «тики», давайте взглянем на документацию :

Объект Date, представленный в JSON как "/ Date (количество тиков) /". Число тиков - это положительное или отрицательное длинное значение, которое указывает число тиков (миллисекунд), прошедшее с полуночи 01 января 1970 года. UT C.

Максимальное поддерживаемое значение даты - MaxValue (12 / 31/9999 11:59:59 PM) и минимальное поддерживаемое значение даты - MinValue (1/1/0001 12:00:00 AM).

Я предполагаю, что в вашем случае у вас есть также предоставляется смещение, как в примерах.

Используя пакет 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;
    }
}

Над отпечатками кода :

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

Сериализатор может выглядеть следующим образом:

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

Вам необходимо правильно обрабатывать часовой пояс, если вы всегда отправляете / получаете дату в UTC, вы можете пропустить эту часть.

См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...