我如何使用杰克逊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"])
当前回答
如果您正在使用fastxml的ObjectMapper类, 默认情况下,ObjectMapper不理解LocalDateTime类,所以,你需要在你的gradle/maven中添加另一个依赖项:
compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.7.3'
现在你需要将这个库提供的数据类型支持注册到你的objectmapper对象中,这可以通过以下方式完成:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.findAndRegisterModules();
现在,在你的jsonString中,你可以很容易地把你的java。LocalDateTime字段如下所示:
{
"user_id": 1,
"score": 9,
"date_time": "2016-05-28T17:39:44.937"
}
通过这样做,你的Json文件到Java对象的转换将工作良好,你可以通过以下方式读取文件:
objectMapper.readValue(jsonString, new TypeReference<List<User>>() {
});
其他回答
这只是一个例子,如何使用它在一个单元测试,我黑调试这个问题。 关键成分是
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());
}
}
您可以在应用程序中设置此参数。yml文件解析即时时间,即java8中的Date API:
spring.jackson.serialization.write-dates-as-timestamps=false
这个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)
如果你考虑使用fastjson,你可以解决你的问题,注意版本
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
如果您因为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