简体   繁体   中英

Jackson converting LocalDatetime

I've a LocalDateTime field with @JsonFormat

@JsonFormat(pattern = "yyyy-MM-dd'T'hh:mm:ss.SSS'Z'")
private LocalDateTime dateTime;

When Jackson try to parse a date like 2018-11-28T15:24:00.000Z a exception is throwed

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.time.LocalDateTime: no String-argument constructor/factory method to deserialize from String value ('2018-11-28T15:24:00.000Z')

In my pom.xml i have:

  • Spring boot 1.5.7
  • jackson-datatype-jdk8
  • jackson-datatype-jsr310

My ObjectMapper Bean:

@Bean
public ObjectMapper postConstruct() {
    return this.builder
           .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .defaultUseWrapper(false)
            .build();
}

I also tried:

@JsonFormat(pattern = "yyyy-MM-dd'T'hh:mm:ss.SSS'Z'", timezone ="UTC")
private LocalDateTime dateTime;

I have faced similar issues. Reason for this issue is that mapper is not able to create a LocalDateTime instance from String object. Below will solve your problem.

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonFormat(pattern = "yyyy-MM-dd'T'hh:mm:ss.SSS'Z'")
private LocalDateTime dateTime;

If you don't want to explicitly mention Serializer/Deseralizer, you will have to do either of below as per JackSon guide for release of DateTime Java 8 enhancements.

ObjectMapper mapper = new ObjectMapper()
   .registerModule(new ParameterNamesModule())
   .registerModule(new Jdk8Module())
   .registerModule(new JavaTimeModule());

OR

ObjectMapper mapper = new ObjectMapper();
mapper.findAndRegisterModules();

In SpringBoot, ObjectMapper instance is AutoWired & hence I don't know if we can explicitly do either of the solution. So for time being, dirty solution of explicitly mentioning Serializer/Deserializer is my best bet.

JackSon Java8 LocalDateTime enhancement ReadMe page is as below

https://github.com/FasterXML/jackson-modules-java8/blob/master/README.md

I also faced this issue when using OffsetDateTime . I simply added @JsonSerialize and @JsonDeserialize (wrote custom deserializer by extending JsonDeserializer<> ) along with format. The issue got solved.

I also faced same issue and wrote custom serializer and de-serializer to solve the problem.

Below are the code snippets for the same:

import static java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME;
import java.io.IOException;
import java.time.LocalDateTime;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.node.TextNode;

public class JsonDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

@Override
public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
        JsonProcessingException {
    ObjectCodec oc = jp.getCodec();
    TextNode node = (TextNode) oc.readTree(jp);
    String dateString = node.textValue();
    return LocalDateTime.parse(dateString, ISO_OFFSET_DATE_TIME);
    }
}


import static java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME;
import java.io.IOException;
import java.time.LocalDateTime;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class JsonDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime date, JsonGenerator generator, SerializerProvider arg) throws IOException,
            JsonProcessingException {
        final String dateString = date.format(ISO_OFFSET_DATE_TIME);
        generator.writeString(dateString);
    }
}

**Using the above custom serializer and deserializer on the below request payload:**

    @JsonDeserialize(using = JsonDateTimeDeserializer.class)
    @JsonSerialize(using = JsonDateTimeSerializer.class)
    private LocalDateTime orderInitialized;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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