杰克逊转换LocalDatetime

时间:2018-12-17 18:19:51

标签: java spring-boot jackson

我有一个@JsonFormat的LocalDateTime字段

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

当Jackson尝试解析诸如 2018-11-28T15:24:00.000Z 之类的日期时,会抛出异常

  

com.fasterxml.jackson.databind.JsonMappingException:无法构造java.time.LocalDateTime的实例:no字符串参数构造函数/工厂方法从字符串值反序列化('2018-11-28T15:24:00.000Z' )

在我的pom.xml中,我有:

  • 春季启动1.5.7
  • jackson-datatype-jdk8
  • jackson-datatype-jsr310

我的ObjectMapper Bean:

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

我也尝试过:

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

3 个答案:

答案 0 :(得分:0)

我也遇到过类似的问题。出现此问题的原因是,映射器无法从String对象创建LocalDateTime实例。下面将解决您的问题。

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

如果您不想明确提及Serializer / Deseralizer,则必须按照JackSon指南中的任何一项进行操作,以发布DateTime Java 8增强功能。

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

OR

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

在SpringBoot中,ObjectMapper实例是AutoWired,因此我不知道我们是否可以显式地执行任一解决方案。所以暂时,明确提到Serializer / Deserializer的肮脏解决方案是我最好的选择。

JackSon Java8 LocalDateTime增强自述页面如下

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

答案 1 :(得分:0)

在使用OffsetDateTime时,我也遇到了这个问题。我只是添加了@JsonSerialize@JsonDeserialize(通过扩展JsonDeserializer<>编写了自定义解串器)以及格式。这个问题解决了。

答案 2 :(得分:0)

我也遇到了同样的问题,并编写了自定义序列化器和反序列化器来解决该问题。

以下是相同的代码段:

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;