我如何使用杰克逊JSON映射与Java 8 LocalDateTime?
jsonmappingexception:不能实例化类型[简单类型,java.time类]的值。LocalDateTime] from JSON字符串;没有单字符串构造函数/工厂方法(通过引用链:MyDTO["field1"]->SubDTO["date"])
我如何使用杰克逊JSON映射与Java 8 LocalDateTime?
jsonmappingexception:不能实例化类型[简单类型,java.time类]的值。LocalDateTime] from JSON字符串;没有单字符串构造函数/工厂方法(通过引用链:MyDTO["field1"]->SubDTO["date"])
当前回答
这个maven依赖将解决你的问题:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.4</version>
</dependency>
我一直在挣扎的一件事是,在反序列化期间,ZonedDateTime时区被更改为GMT。 结果,Jackson默认用上下文中的一个替换它。 要保留区域1,必须禁用此“功能”
Jackson2ObjectMapperBuilder.json()
.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
其他回答
如果你正在使用Spring引导,并且在OffsetDateTime上有这个问题,那么需要使用上面@greperror回答的registerModules(5月28日16日13:04回答),但注意有一个区别。不需要添加提到的依赖项,因为我猜spring boot已经有它了。我有这个问题与春季启动,它为我工作,没有添加这个依赖。
这只是一个例子,如何使用它在一个单元测试,我黑调试这个问题。 关键成分是
mapper。registerModule(从新JavaTimeModule (); <artifactId>jack -datatyp -jsr310</artifactId>的maven dependency
代码:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.IOException;
import java.io.Serializable;
import java.time.Instant;
class Mumu implements Serializable {
private Instant from;
private String text;
Mumu(Instant from, String text) {
this.from = from;
this.text = text;
}
public Mumu() {
}
public Instant getFrom() {
return from;
}
public String getText() {
return text;
}
@Override
public String toString() {
return "Mumu{" +
"from=" + from +
", text='" + text + '\'' +
'}';
}
}
public class Scratch {
@Test
public void JacksonInstant() throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
Mumu before = new Mumu(Instant.now(), "before");
String jsonInString = mapper.writeValueAsString(before);
System.out.println("-- BEFORE --");
System.out.println(before);
System.out.println(jsonInString);
Mumu after = mapper.readValue(jsonInString, Mumu.class);
System.out.println("-- AFTER --");
System.out.println(after);
Assert.assertEquals(after.toString(), before.toString());
}
}
在Jackson JSR的新版本中,例如,registerModule(new JSR310Module())已弃用,现在建议使用JavaTimeModule
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonFactory {
private static ObjectMapper objectMapper = null;
public static ObjectMapper getObjectMapper() {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
}
return objectMapper;
}
}
如果有人在使用SpringBoot时遇到问题,这里是我在不添加新的依赖项的情况下修复问题的方法。
在Spring 2.1.3中,Jackson期望在此yyyy-MM-dd HH:mm:ss中出现日期字符串2019-05-21T07:37:11.000。在LocalDateTime中反序列化SSS格式。确保日期字符串用T分隔日期和时间,而不是用空格。秒(ss)和毫秒(SSS)可以省略。
@JsonProperty("last_charge_date")
public LocalDateTime lastChargeDate;
如果您因为GraphQL Java工具而遇到此问题,并试图从日期字符串编组Java Instant,则需要设置SchemaParser以使用具有特定配置的ObjectMapper:
在GraphQLSchemaBuilder类中,注入ObjectMapper并添加以下模块:
ObjectMapper objectMapper =
new ObjectMapper().registerModule(new JavaTimeModule())
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
并将其添加到选项中:
final SchemaParserOptions options = SchemaParserOptions.newOptions()
.objectMapperProvider(fieldDefinition -> objectMapper)
.typeDefinitionFactory(new YourTypeDefinitionFactory())
.build();
参见https://github.com/graphql-java-kickstart/graphql-spring-boot/issues/32