serialize/deserialize java 8 java.time with Jackson JSON mapper

后端 未结 17 1140
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 15:56

How do I use Jackson JSON mapper with Java 8 LocalDateTime?

org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple t

相关标签:
17条回答
  • 2020-11-22 16:42

    If you're having this issue because of GraphQL Java Tools and trying to marshal an Java Instant from a date string, you need to setup your SchemaParser to use an ObjectMapper with certain configurations:

    In your GraphQLSchemaBuilder class, inject ObjectMapper and add this modules:

            ObjectMapper objectMapper = 
        new ObjectMapper().registerModule(new JavaTimeModule())
                .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    

    and add it to the options:

    final SchemaParserOptions options = SchemaParserOptions.newOptions()
                .objectMapperProvider(fieldDefinition -> objectMapper)
                .typeDefinitionFactory(new YourTypeDefinitionFactory())
                .build();
    

    See https://github.com/graphql-java-kickstart/graphql-spring-boot/issues/32

    0 讨论(0)
  • 2020-11-22 16:42

    If any one having problem while using SpringBoot here is how I fixed the issue without adding new dependency.

    In Spring 2.1.3 Jackson expects date string 2019-05-21T07:37:11.000 in this yyyy-MM-dd HH:mm:ss.SSS format to de-serialize in LocalDateTime. Make sure date string separates the date and time with T not with space. seconds (ss) and milliseconds(SSS) could be ommitted.

    @JsonProperty("last_charge_date")
    public LocalDateTime lastChargeDate;
    
    0 讨论(0)
  • 2020-11-22 16:47

    There's no need to use custom serializers/deserializers here. Use jackson-modules-java8's datetime module:

    Datatype module to make Jackson recognize Java 8 Date & Time API data types (JSR-310).

    This module adds support for quite a few classes:

    • Duration
    • Instant
    • LocalDateTime
    • LocalDate
    • LocalTime
    • MonthDay
    • OffsetDateTime
    • OffsetTime
    • Period
    • Year
    • YearMonth
    • ZonedDateTime
    • ZoneId
    • ZoneOffset
    0 讨论(0)
  • 2020-11-22 16:47

    If you are using ObjectMapper class of fasterxml, by default ObjectMapper do not understand the LocalDateTime class, so, you need to add another dependency in your gradle/maven :

    compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.7.3'
    

    Now you need to register the datatype support offered by this library into you objectmapper object, this can be done by following :

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

    Now, in your jsonString, you can easily put your java.LocalDateTime field as follows :

    {
        "user_id": 1,
        "score": 9,
        "date_time": "2016-05-28T17:39:44.937"
    }
    

    By doing all this, your Json file to Java object conversion will work fine, you can read the file by following :

    objectMapper.readValue(jsonString, new TypeReference<List<User>>() {
                });
    
    0 讨论(0)
  • 2020-11-22 16:47

    If you are using Spring boot and have this issue with the OffsetDateTime then need to use the registerModules as answered above by @greperror(answered May 28 '16 at 13:04) but note that there is one difference. The dependency mentioned doesn't need to be added as I am guessing that spring boot has it already. I was having this issue with Spring boot and it worked for me without adding this dependency.

    0 讨论(0)
  • 2020-11-22 16:49

    If you are using Jackson Serializer, here is a way to use the date modules:

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题