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

后端 未结 17 1141
隐瞒了意图╮
隐瞒了意图╮ 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:50

    Update: Leaving this answer for historical reasons, but I don't recommend it. Please see the accepted answer above.

    Tell Jackson to map using your custom [de]serialization classes:

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime ignoreUntil;
    

    provide custom classes:

    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
            arg1.writeString(arg0.toString());
        }
    }
    
    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException {
            return LocalDateTime.parse(arg0.getText());
        }
    }
    

    random fact: if i nest above classes and don't make them static, the error message is weird: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported

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

    If you consider using fastjson, you can solve your problem, note the version

     <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
     </dependency>
    
    0 讨论(0)
  • 2020-11-22 16:54

    I had a similar problem while using Spring boot. With Spring boot 1.5.1.RELEASE all I had to do is to add dependency:

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
    
    0 讨论(0)
  • 2020-11-22 16:57

    If you can't use jackson-modules-java8 for whatever reasons you can (de-)serialize the instant field as long using @JsonIgnore and @JsonGetter & @JsonSetter:

    public class MyBean {
    
        private Instant time = Instant.now();
    
        @JsonIgnore
        public Instant getTime() {
            return this.time;
        }
    
        public void setTime(Instant time) {
            this.time = time;
        }
    
        @JsonGetter
        private long getEpochTime() {
            return this.time.toEpochMilli();
        }
    
        @JsonSetter
        private void setEpochTime(long time) {
            this.time = Instant.ofEpochMilli(time);
        }
    }
    

    Example:

    @Test
    public void testJsonTime() throws Exception {
        String json = new ObjectMapper().writeValueAsString(new MyBean());
        System.out.println(json);
        MyBean myBean = new ObjectMapper().readValue(json, MyBean.class);
        System.out.println(myBean.getTime());
    }
    

    yields

    {"epochTime":1506432517242}
    2017-09-26T13:28:37.242Z
    
    0 讨论(0)
  • 2020-11-22 16:58

    For those who use Spring Boot 2.x

    There is no need to do any of the above - Java 8 LocalDateTime is serialised/de-serialised out of the box. I had to do all of the above in 1.x, but with Boot 2.x, it works seamlessly.

    See this reference too JSON Java 8 LocalDateTime format in Spring Boot

    0 讨论(0)
提交回复
热议问题