无法从START_OBJECT令牌中反序列化org.joda.time.DateTime或LocalDate的实例

时间:2012-11-27 20:28:05

标签: spring-mvc jackson

v2.1.1,joda module.

我可以使用objectMapper.readValue(file,pojo .class)在单元测试中将json文件转换为pojo;

但是,当Spring RESTTemplate客户端调用default json converter转换包含具有Joda类型(DateTime或LocalDate)的域对象的inputStream时,它会生成错误:objectMapper.readValue(httpInputMessage.getBody(), javaType)

   
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.joda.time.DateTime out of START_OBJECT token
at Source: org.mortbay.jetty.HttpParser$Input@46a09b; line: 1, column: 752
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:599)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:593)
at com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer.deserialize(DateTimeDeserializer.java:51)
at com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer.deserialize(DateTimeDeserializer.java:21)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:559)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:393)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:289)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:106)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserializeFromObject(BuilderBasedDeserializer.java:326)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserialize(BuilderBasedDeserializer.java:143)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:106)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserializeFromObject(BuilderBasedDeserializer.java:

LocalDate

出现同样的问题
com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: expected JSON Array, String or Number
at Source: org.mortbay.jetty.HttpParser$Input@d297c0; line: 1, column: 51
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:692)
at com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:50)
....

为什么调用链在一个案例中传递START_OBJECT而在另一个案例中传递START_ARRAY?

4 个答案:

答案 0 :(得分:19)

为解决类似问题,我做了以下工作,

我从http://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-joda/2.2.1下载了jackson-datatype-joda-2.2.1.jar如果您正在使用maven,依赖项定义也在那里。

然后我为我的应用中的每个LocalDate字段添加了一个注释,如下所示:

@JsonDeserialize(using=LocalDateDeserializer.class)
private LocalDate releasedDate;

导入如下所示:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer;

问题消失了。

希望这有帮助!

答案 1 :(得分:5)

我认为这与序列化器和解串器之间的一些差异有关;所以一个产生另一个(我认为Joda模块实际上在注册时写入一个int数组)。 这很可能是因为缺少解串器或序列化器注册。

默认情况下,没有任何额外处理,杰克逊会认为Joda类型只是POJO,并使用getter / setter。但Joda模块使用更紧凑的表示(字符串,数组)。 所以可能发生的是序列化方面没有使用Joda模块;和反序列化是。

答案 2 :(得分:3)

你应该为joda-time使用序列化和反序列化;反对你试图保存和获取的那些字段 通过这样做,我们将向jackson(java到mongo / json和mongo / json到java转换)提供双方责任。

示例代码:

@JsonDeserialize(using= LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
LocalDate dateFieldToBeConverted

这些是进口商品:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize

import com.fasterxml.jackson.databind.annotation.JsonSerialize

import com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer

import com.fasterxml.jackson.datatype.joda.ser.LocalDateSerializer

import org.joda.time.LocalDate

执行此操作后,对mongo(通过java repo类)的简单save和findOne查询将无任何问题地工作。希望这会有所帮助。

答案 3 :(得分:0)

这里的关键问题是Spring正在以不同的方式转换JodaTime,例如Jersey。

这就是我在app-servlet.xml中所要做的事情:

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean"/>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

您可以在此处找到no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean资料库中的java-json-client