18

我正在使用描述Jackson Datatype JSR310 页面的库,但我仍然很难让它工作。

我已经配置了以下bean:

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

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

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

杰克逊最后一直在抱怨“Z”。如果我在LocalDateTimeDeserializer文档中查看它使用DateTimeFormatter.ISO_LOCAL_DATE_TIMEwhich 沸腾ISO_LOCAL_DATE'T'ISO_LOCAL_TIME并提到它没有覆盖区域。

所以我想我应该设置我正在创建DateFormat的:ObjectMapper

@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 格式...

4

3 回答 3

35

不必编写自己的序列化程序。使用默认的就足够了,但是使用另一种格式(那个)制作一个实例,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;
    }  
}
于 2015-11-05T14:10:55.390 回答
5

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

为了使其工作,您可以覆盖LocalDateTimeDeserializer或切换到使用ZoneDateTime最后处理“Z”字符的方法。

这是一个例子:

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]
于 2015-04-11T16:33:28.323 回答
2

Hibernate 4,Spring 4 - REST WS,客户端 - Spring Boot 1.5.2。在我的例子中,我在 Entity ZonedDateTime类中使用来映射数据库中的时间戳。Hibernate 和 Spring Boot REST 工作正常。我必须只将库添加到pom文件中:

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 -->
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
    </dependency>

所以我想,该转换器也是在 Spring 中为LocalDateTime实现的。jackson.version是最新的。

于 2017-07-28T14:17:21.970 回答