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?
答案 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