我如何使用杰克逊JSON映射与Java 8 LocalDateTime?

jsonmappingexception:不能实例化类型[简单类型,java.time类]的值。LocalDateTime] from JSON字符串;没有单字符串构造函数/工厂方法(通过引用链:MyDTO["field1"]->SubDTO["date"])


当前回答

        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-parameter-names</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jdk8</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>

添加这些依赖项并启用这些模块。这应该会有帮助

    private static final ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();

其他回答

您可以在应用程序中设置此参数。yml文件解析即时时间,即java8中的Date API:

spring.jackson.serialization.write-dates-as-timestamps=false

如果你考虑使用fastjson,你可以解决你的问题,注意版本

 <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.56</version>
 </dependency>

如果你正在使用Jackson Serializer,下面是一种使用date模块的方法:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.apache.kafka.common.serialization.Serializer;

public class JacksonSerializer<T> implements Serializer<T> {

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

    @Override
    public byte[] serialize(String s, T object) {
        try {
            return mapper.writeValueAsBytes(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

如果您正在使用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>>() {
            });

如果您因为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