Deserialize Java 8 LocalDateTime with JacksonMapper

后端 未结 6 1241
孤城傲影
孤城傲影 2020-11-28 09:30

I have read several questions with answers here in SO concerning serialization and deserialization between java.time.LocalDateTime and JSON property but I can\'

相关标签:
6条回答
  • 2020-11-28 10:20

    You used wrong letter case for year in line:

    @JsonFormat(pattern = "YYYY-MM-dd HH:mm")
    

    Should be:

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    

    With this change everything is working as expected.

    0 讨论(0)
  • 2020-11-28 10:20

    This worked for me:

     @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", shape = JsonFormat.Shape.STRING)
     private LocalDateTime startDate;
    
    0 讨论(0)
  • 2020-11-28 10:20

    UPDATE:

    Change to:

    @Column(name = "start_date")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm", iso = ISO.DATE_TIME)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm")
    private LocalDateTime startDate;
    

    JSON request:

    {
     "startDate":"2019-04-02 11:45"
    }
    
    0 讨论(0)
  • 2020-11-28 10:21

    You can implement your JsonSerializer

    See:

    That your propertie in bean

    @JsonProperty("start_date")
    @JsonFormat("YYYY-MM-dd HH:mm")
    @JsonSerialize(using = DateSerializer.class)
    private Date startDate;
    

    That way implement your custom class

    public class DateSerializer extends JsonSerializer<Date> implements ContextualSerializer<Date> {
    
        private final String format;
    
        private DateSerializer(final String format) {
            this.format = format;
        }
    
        public DateSerializer() {
            this.format = null;
        }
    
        @Override
        public void serialize(final Date value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException {
            jgen.writeString(new SimpleDateFormat(format).format(value));
        }
    
        @Override
        public JsonSerializer<Date> createContextual(final SerializationConfig serializationConfig, final BeanProperty beanProperty) throws JsonMappingException {
            final AnnotatedElement annotated = beanProperty.getMember().getAnnotated();
            return new DateSerializer(annotated.getAnnotation(JsonFormat.class).value());
        }
    
    }
    

    Try this after post result for us.

    0 讨论(0)
  • 2020-11-28 10:27

    This worked for me :

    import org.springframework.format.annotation.DateTimeFormat;
    import org.springframework.format.annotation.DateTimeFormat.ISO;
    
    @Column(name="end_date", nullable = false)
    @DateTimeFormat(iso = ISO.DATE_TIME)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private LocalDateTime endDate;
    
    0 讨论(0)
  • 2020-11-28 10:29

    The date time you're passing is not a iso local date time format.

    Change to

    @Column(name = "start_date")
    @DateTimeFormat(iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    @JsonFormat(pattern = "YYYY-MM-dd HH:mm")
    private LocalDateTime startDate;
    

    and pass date string in the format '2011-12-03T10:15:30'.

    But if you still want to pass your custom format, use just have to specify the right formatter.

    Change to

    @Column(name = "start_date")
    @DateTimeFormat(iso = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
    @JsonFormat(pattern = "YYYY-MM-dd HH:mm")
    private LocalDateTime startDate;
    

    I think your problem is the @DateTimeFormat has no effect at all. As the jackson is doing the deseralization and it doesnt know anything about spring annotation and I dont see spring scanning this annotation in the deserialization context.

    Alternatively, you can try setting the formatter while registering the java time module.

    LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
    module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
    

    Here is the test case with the deseralizer which works fine. May be try to get rid of that DateTimeFormat annotation altogether.

    @RunWith(JUnit4.class)
    public class JacksonLocalDateTimeTest {
    
        private ObjectMapper objectMapper;
    
        @Before
        public void init() {
            JavaTimeModule module = new JavaTimeModule();
            LocalDateTimeDeserializer localDateTimeDeserializer =  new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
            objectMapper = Jackson2ObjectMapperBuilder.json()
                    .modules(module)
                    .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                    .build();
        }
    
        @Test
        public void test() throws IOException {
            final String json = "{ \"date\": \"2016-11-08 12:00\" }";
            final JsonType instance = objectMapper.readValue(json, JsonType.class);
    
            assertEquals(LocalDateTime.parse("2016-11-08 12:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") ), instance.getDate());
        }
    }
    
    
    class JsonType {
        private LocalDateTime date;
    
        public LocalDateTime getDate() {
            return date;
        }
    
        public void setDate(LocalDateTime date) {
            this.date = date;
        }
    }
    
    0 讨论(0)
提交回复
热议问题