18

v2.1.1,乔达模块。

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

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

   
com.fasterxml.jackson.databind.JsonMappingException:无法反序列化 START_OBJECT 令牌中的 org.joda.time.DateTime 实例
来源:org.mortbay.jetty.HttpParser$Input@46a09b;行:1,列:752
在 com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
在 com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:599)
在 com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:593)
在 com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer.deserialize(DateTimeDeserializer.java:51)
在 com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer.deserialize(DateTimeDeserializer.java:21)
在 com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
在 com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:559)
在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:393)
在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:289)
在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
在 com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
在 com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:106)
在 com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserializeFromObject(BuilderBasedDeserializer.java:326)
在 com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserialize(BuilderBasedDeserializer.java:143)
在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
在 com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
在 com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:106)
在 com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserializeFromObject(BuilderBasedDeserializer.java:

LocalDate 也会出现同样的问题

com.fasterxml.jackson.databind.JsonMappingException:意外令牌 (START_OBJECT),预期 START_ARRAY:预期 JSON 数组、字符串或数字
来源:org.mortbay.jetty.HttpParser$Input@d297c0;行:1,列:51
在 com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
在 com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:692)
在 com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:50)
……

为什么调用链在一种情况下传递 START_OBJECT 而在另一种情况下传递 START_ARRAY?

4

4 回答 4

20

为了解决类似的问题,我做了以下事情,

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

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

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

进口看起来像这样:

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

问题消失了。

希望这可以帮助!

于 2013-06-06T21:57:32.227 回答
6

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

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

于 2012-11-28T03:45:16.360 回答
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 上的简单 save 和 findOne 查询(通过 java repo 类)将毫无问题地工作。希望这可以帮助。

于 2016-02-08T13:30:01.213 回答
0

这里的关键问题是 Spring 以不同于 Jersey 的方式转换 JodaTime。

这是我必须在我的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>

在这里,您可以从java-json-client库中找到no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean

于 2014-10-17T12:00:16.227 回答