使用 Jackson JSR310 模块反序列化 LocalDateTime

2022-09-02 11:50:25

我正在使用描述杰克逊数据类型JSR310页面的库,但我仍然难以使其正常工作。

我已经配置了以下bean:

@Bean
@Primary
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JSR310Module());
    return mapper;
}

当我调用我的 REST API 时,日期格式输出是 ,例如 .这可以通过我的AngularJS代码处理得很好。yyyy-MM-dd'T'HH:ss.SSSSSS2015-04-11T00:10:38.905847

当我想向 REST API 提交内容时,日期将发布为 ,例如yyyy-MM-dd'T'HH:mm:ss.SSS'Z'2015-04-09T08:30:00.000Z

杰克逊在最后一直抱怨“Z”。如果我看一下文档中的,它使用哪个沸腾,它提到它没有覆盖区域。LocalDateTimeDeserializerDateTimeFormatter.ISO_LOCAL_DATE_TIMEISO_LOCAL_DATE'T'ISO_LOCAL_TIME

所以我想我应该在我正在创建的上设置:DateFormatObjectMapper

@Bean
@Primary
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JSR310Module());
    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
    return mapper;
}

但这无济于事。我将其更改为简单的东西,但序列化日期仍保留为以前的格式,反序列化也不受影响。yyyy-MM-dd

我在这里做错了什么才能让它发挥作用?据我所知,我的JavaScript代码中的日期格式是ISO 8601格式...


答案 1

无需编写自己的序列化程序。使用默认的那个就足够了,但是用另一种格式(那个)制作一个实例,这样超过的部分就会被剪切掉:time_zone

new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)

在我的情况下,我有一个这样的配置级别实现:contextResolver

@Service 
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {  
    private final ObjectMapper mapper;

    public ObjectMapperContextResolver() {
        mapper = new ObjectMapper();
        JavaTimeModule javaTimeModule=new JavaTimeModule();
        // Hack time module to allow 'Z' at the end of string (i.e. javascript json's) 
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
        mapper.registerModule(javaTimeModule);
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }  
}

答案 2

目前,似乎不考虑为对象映射器设置的日期格式。LocalDateTimeDeserializer

要使其正常工作,您可以覆盖或切换到使用哪个处理末尾的“Z”字符。LocalDateTimeDeserializerZoneDateTime

下面是一个示例:

public class Java8DateFormat {
    public static void main(String[] args) throws IOException {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JSR310Module());
        // mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));

        final String date = mapper.writeValueAsString(new Date());
        System.out.println(date);
        System.out.println(mapper.readValue(date, ZonedDateTime.class));
    }
}

输出:

"2015-04-11T18:24:47.815Z"
2015-04-11T18:24:47.815Z[GMT]

推荐