Java Jackson将从ISO DateTime反序列化Joda LocalDate

Java Jackson将从ISO DateTime反序列化Joda LocalDate,java,datetime,jackson,jodatime,date-parsing,Java,Datetime,Jackson,Jodatime,Date Parsing,我使用Angular日期选择器向MVC控制器发送一个日期,使用一个Javascript日期对象,它是ISO日期/时间 反序列化java.util.Date时,它就像一个符咒,Hibernate在插入记录时会关心将Date时间缩短为一个普通日期 但是现在我正从java.util.Date过渡到org.joda.time.[这里是适当的类]我面临着这个反序列化问题 我的理解是,如果我在DTOs中强制执行DateTime,Jackson将正确地对它们进行反序列化,而相反,当目标类型是日期时,我更喜欢删

我使用Angular日期选择器向MVC控制器发送一个日期,使用一个Javascript日期对象,它是ISO日期/时间

反序列化
java.util.Date
时,它就像一个符咒,Hibernate在插入记录时会关心将
Date
时间缩短为一个普通日期

但是现在我正从
java.util.Date
过渡到
org.joda.time.[这里是适当的类]
我面临着这个反序列化问题

我的理解是,如果我在DTOs中强制执行
DateTime
,Jackson将正确地对它们进行反序列化,而相反,当目标类型是日期时,我更喜欢删除时间信息

例如

相反,我得到的是:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Invalid format: "2017-07-13T10:00:00.000Z" is malformed at "T10:00:00.000Z"; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Invalid format: "2017-07-13T10:00:00.000Z" is malformed at "T10:00:00.000Z" (through reference chain: it.phoenix.web.data.dtos.admin.profile.UserDTO["passwordExpirationDate"])
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:244) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Invalid format: "2017-07-13T10:00:00.000Z" is malformed at "T10:00:00.000Z" (through reference chain: it.phoenix.web.data.dtos.admin.profile.UserDTO["passwordExpirationDate"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:388) ~[jackson-databind-2.8.9.jar:2.8.9]
Caused by: java.lang.IllegalArgumentException: Invalid format: "2017-07-13T10:00:00.000Z" is malformed at "T10:00:00.000Z"
    at org.joda.time.format.DateTimeFormatter.parseLocalDateTime(DateTimeFormatter.java:900) ~[joda-time-2.9.9.jar:2.9.9]
    at org.joda.time.format.DateTimeFormatter.parseLocalDate(DateTimeFormatter.java:844) ~[joda-time-2.9.9.jar:2.9.9]
    at com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:39) ~[jackson-datatype-joda-2.8.9.jar:2.8.9]
    at com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:15) ~[jackson-datatype-joda-2.8.9.jar:2.8.9]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504) ~[jackson-databind-2.8.9.jar:2.8.9]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104) ~[jackson-databind-2.8.9.jar:2.8.9]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357) ~[jackson-databind-2.8.9.jar:2.8.9]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.9.jar:2.8.9]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3814) ~[jackson-databind-2.8.9.jar:2.8.9]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2938) ~[jackson-databind-2.8.9.jar:2.8.9]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:241) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    ... 92 more
问题是:有没有一种聪明的方法可以让Jackson通过简单地剥离默认/当前时区的时间部分,将DateTime对象解码成Joda
LocalDate

注: -我已经有了Jackson Joda模块依赖项 -杰克逊是2.8.9
-我被迫使用Java7。在一个相关的Java 8项目中,我对Java没有这样的问题。
time
stuff(和Jackson JSR310模块)

根据错误消息,日期/时间输入为
2017-07-13T10:00:00.000Z
,默认情况下,
LocalDate
无法处理它

您可以使用
LocalDate
字段中的
com.fasterxml.jackson.annotation.JsonFormat
注释来配置此格式:

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
private LocalDate passwordExpirationDate;

这将使Jackson正确解析日期。

以下内容在我的Spring上下文配置中对我有效

<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" id="pnxObjectMapper">
    <property name="deserializersByType">
        <map key-type="java.lang.Class">
            <entry>
                <key>
                    <value>org.joda.time.LocalDate</value>
                </key>
                <bean class="com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer">
                    <constructor-arg>
                        <util:constant static-field="com.fasterxml.jackson.datatype.joda.cfg.FormatConfig.DEFAULT_DATETIME_PARSER" />
                    </constructor-arg>
                </bean>
            </entry>
        </map>
    </property>
</bean>

org.joda.time.LocalDate

说明:在加载JodaModule之前,它为
LocalDate
s定义了一个反序列化程序,并正确地采用了ISO纯日期格式,我强制Spring在构建序列化程序时更改格式化程序,我想您在创建
ObjectMapper
时可以注册一些模块

public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    objectMapper.registerModule(new JavaTimeModule());
    objectMapper.registerModule(new JodaModule());
    return objectMapper;
}
并将其放入Spring配置中的消息转换器中

MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper());

// Configuration class
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(mappingJackson2HttpMessageConverter());
}
MappingJackson2HttpMessageConverter=新的MappingJackson2HttpMessageConverter();
setObjectMapper(objectMapper());
//配置类
@配置
公共类WebMvcConfig扩展了WebMvcConfigurationSupport{
@凌驾

公共无效配置MessageConverters(列表是否有机会在全球范围内应用此解决方案…嗯…类路径范围?还有…我刚刚完成了一个建议的解决方案的测试。我会将其作为答案发布。如果您可以帮助我将上述内容应用于LocalDate类型的每个属性,我将授予您接受的答案,因为我不喜欢我的解决方案如何配置jackson?您是否创建
对象Mapper
手动或使用特定角度的配置文件配置它?@usr local-ΕψΕ∧Ν我打算确切地建议您正在做什么。我不经常使用Jackson,所以这是我知道的唯一替代方法:用所需格式注释所有字段,或更改该类型所有字段的反序列化程序。我得到了这个错误
JSON分析错误:无法从字符串“2017-12-31T23:00:00.000Z”反序列化“java.time.LocalDate”类型的值
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper());

// Configuration class
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(mappingJackson2HttpMessageConverter());
}