java.util.time.LocalDateTime 反序列化为 joda LocalDateTime
Deserialization of java.util.time.LocalDateTime to joda LocalDateTime
我有 REST 网络服务公开资源和创建日期。它是用 Java 8 编写的 - 使用 LocalDateTime。 Jackson 2 正在将其序列化为:
"createdDate": [2016, 5, 19, 18, 6, 59, 639000000]
在其他应用程序中我的目标是消耗这个休息,但只有 Java 7,所以我决定在 DTO 中使用 joda-time 库。我已经像这样设置了 RestTemplate:
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter e = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
e.setObjectMapper(mapper);
messageConverters.add(e);
restTemplate.setMessageConverters(messageConverters);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<NewUserData> request = new HttpEntity<>(user, headers);
POST 成功,但是在反序列化答案时(使用上面的 createdDate 字段)抛出异常:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Value 696000000 for millisOfSecond must be in the range [0,999] (through reference chain: com.foobar.dto.user.UserItem["createdDate"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Value 696000000 for millisOfSecond must be in the range [0,999] (through reference chain: com.foobar.dto.user.UserDisplayItem["createdDate"])
我的依赖项如下所示:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.7.4</version>
</dependency>
我应该编写自己的 Jackson 解串器还是可以使用其他 library/version?
我相信 Jackson 将 Java 8 个时间类型与 nanosecond precision by default, while Joda-Time only supports milliseconds. What you'd need in your server written in Java 8 is to serialize the LocalDateTime
属性 序列化为 "createdDate": [2016, 5, 19, 18, 6, 59, 639]
而不是 "createdDate": [2016, 5, 19, 18, 6, 59, 639000000]
.
您可以在 Java 8 服务器中更改此行为,方法是配置您用于序列化的 ObjectMapper
实例:
ObjectMapper mapper = ... //this is the instance used to serialize the data
mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
如果您不能或不想更改 Java 8 服务器,Jackson 有相应的 DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS
标志。可悲的是,我不认为 joda module supports it at the moment (see implementation)。因此,我认为您现在唯一的选择是实现自定义反序列化器,或者更好的是,提交对 joda 模块进行改进的 PR。
我已经解决了我的问题。这是我在服务器上的新杰克逊配置(而不是使用默认配置):
private MappingJackson2HttpMessageConverter customMappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.setDateFormat(new ISO8601DateFormat());
objectMapper.registerModule(new JavaTimeModule());
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(customMappingJackson2HttpMessageConverter());
}
注册模块、禁用将日期写为时间戳并注册 JavaTimeModule 完成了这项工作。多亏了这一点,服务器将日期序列化为:
"createdDate":"2016-06-07T15:15:25"
在客户端应用程序中,我必须更改 jackson 配置并添加:
mapper.setDateFormat(new ISO8601DateFormat());
我有 REST 网络服务公开资源和创建日期。它是用 Java 8 编写的 - 使用 LocalDateTime。 Jackson 2 正在将其序列化为:
"createdDate": [2016, 5, 19, 18, 6, 59, 639000000]
在其他应用程序中我的目标是消耗这个休息,但只有 Java 7,所以我决定在 DTO 中使用 joda-time 库。我已经像这样设置了 RestTemplate:
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter e = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
e.setObjectMapper(mapper);
messageConverters.add(e);
restTemplate.setMessageConverters(messageConverters);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<NewUserData> request = new HttpEntity<>(user, headers);
POST 成功,但是在反序列化答案时(使用上面的 createdDate 字段)抛出异常:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Value 696000000 for millisOfSecond must be in the range [0,999] (through reference chain: com.foobar.dto.user.UserItem["createdDate"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Value 696000000 for millisOfSecond must be in the range [0,999] (through reference chain: com.foobar.dto.user.UserDisplayItem["createdDate"])
我的依赖项如下所示:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.7.4</version>
</dependency>
我应该编写自己的 Jackson 解串器还是可以使用其他 library/version?
我相信 Jackson 将 Java 8 个时间类型与 nanosecond precision by default, while Joda-Time only supports milliseconds. What you'd need in your server written in Java 8 is to serialize the LocalDateTime
属性 序列化为 "createdDate": [2016, 5, 19, 18, 6, 59, 639]
而不是 "createdDate": [2016, 5, 19, 18, 6, 59, 639000000]
.
您可以在 Java 8 服务器中更改此行为,方法是配置您用于序列化的 ObjectMapper
实例:
ObjectMapper mapper = ... //this is the instance used to serialize the data
mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
如果您不能或不想更改 Java 8 服务器,Jackson 有相应的 DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS
标志。可悲的是,我不认为 joda module supports it at the moment (see implementation)。因此,我认为您现在唯一的选择是实现自定义反序列化器,或者更好的是,提交对 joda 模块进行改进的 PR。
我已经解决了我的问题。这是我在服务器上的新杰克逊配置(而不是使用默认配置):
private MappingJackson2HttpMessageConverter customMappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.setDateFormat(new ISO8601DateFormat());
objectMapper.registerModule(new JavaTimeModule());
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(customMappingJackson2HttpMessageConverter());
}
注册模块、禁用将日期写为时间戳并注册 JavaTimeModule 完成了这项工作。多亏了这一点,服务器将日期序列化为:
"createdDate":"2016-06-07T15:15:25"
在客户端应用程序中,我必须更改 jackson 配置并添加:
mapper.setDateFormat(new ISO8601DateFormat());