Десериализовать LocalDateTime из строки с Джексоном - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь десериализовать String до LocalDateTime с Джексоном, но это не работает.

У меня есть класс данных с полем LocalDateTime:

@Data
public class Registration {
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    private LocalDateTime timestamp;
}

Я добавил специальные модули типов данных Джексона:

compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")

Сериализация отлично работает с:

new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(registration);

Строка результата:

{"timestamp":"2018-09-03 10:09:35"}

Но десериализация не работает с:

new ObjectMapper().registerModule(new JavaTimeModule()).readValue(json.traverse(), Registration.class)

В качестве ошибки я получаю:

Cannot deserialize value of type `java.time.LocalDateTime` from String "2018-09-03 10:09:35": 
    Failed to deserialize java.time.LocalDateTime: 
        (java.time.format.DateTimeParseException) Text '2018-09-03 10:09:35' could not be parsed: 
            Unable to obtain LocalDateTime from TemporalAccessor: 
                {MinuteOfHour=9, NanoOfSecond=0, SecondOfMinute=35, MicroOfSecond=0, MilliOfSecond=0, HourOfAmPm=10},
                ISO resolved to 2018-09-03 of type java.time.format.Parsed

Что мне не хватает? Я запутался, что сериализация работает, а десериализация - нет.


MWE: (небольшой проект Java)

Main.java:

import java.io.IOException;
import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class Main {

    public static void main(String[] args) throws IOException {
        Registration registration = new Registration();
        registration.setTimestamp(LocalDateTime.now());

         ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());

         String s = objectMapper.writeValueAsString(registration);
         TreeNode treeNode = objectMapper.readTree(s);

         //Fails here:
         Registration registration1 = objectMapper.readValue(treeNode.traverse(), Registration.class);

        System.out.println(registration1);
    }
}

class Registration {
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    private LocalDateTime timestamp;

    public Registration() {
    }

    public LocalDateTime getTimestamp() {
        return this.timestamp;
    }

    public void setTimestamp(LocalDateTime localDateTime) {
        this.timestamp = localDateTime;
    }
}

build.gradle:

plugins {
    id 'java'
}

group 'dateMWE'
version '1.0-SNAPSHOT'

sourceCompatibility = 10

repositories {
    mavenCentral()
}

dependencies {
    compile("com.fasterxml.jackson.core:jackson-annotations:2.9.6")
    compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.6")
}

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Spring не управляет вашим ObjectMapper, поскольку вы создаете объект с новым. Настройте ObjectMapper как Bean в вашем файле конфигурации. Вам необходимо зарегистрировать DateTimeFormat с вашим LocalDateTimeDeserializer. Затем установите свой десериализатор в JavaTimeModule.

@Bean
 Public ObjectMapper objectMapper() {
   JavaTimeModule module = new JavaTimeModule();
   LocalDateTimeDeserializer localDateTimeDeserializer =  new 
   LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
   module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
   ObjectMapper objectMapperObj = Jackson2ObjectMapperBuilder.json()
            .modules(module)
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build();
return objectMapperObj ;

Установите вышеуказанную конфигурацию в конфигурации Spring.

0 голосов
/ 03 сентября 2018

Проблема не связана с десериализацией JSON, а скорее со строкой формата времени:

pattern = "yyyy-MM-dd hh:mm:ss"

Обратите внимание, что часы установлены как hh: это 12-часовой форматер, для которого требуются значения "AM" или "PM".

Если шаблон изменен на

pattern = "yyyy-MM-dd HH:mm:ss"

проблема должна быть решена.

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