spring mvc - mvc - No se puede deserializar la instancia de org.joda.time.DateTime o LocalDate fuera del token START_OBJECT
struts vs spring (4)
v2.1.1, módulo joda.
Puedo convertir un archivo json en un pojo en una prueba unitaria usando objectMapper.readValue (archivo, pojo .class);
Sin embargo, cuando un cliente Spring RESTTemplate invoca el convertidor json predeterminado para convertir un inputStream que contiene el objeto de dominio con tipos Joda (DateTime o LocalDate), genera un error: 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:
El mismo problema ocurre con 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) ....
¿Por qué la cadena de llamadas pasa un START_OBJECT en un caso y START_ARRAY en el otro?
Creo que esto tiene que ver con alguna discrepancia entre el serializador y el deserializador; para que uno produzca el otro (creo que el módulo de Joda en realidad escribe una serie de caracteres cuando está registrado). Esto probablemente se deba a que falta el deserializador o el registro del serializador.
Por defecto, sin ningún manejo adicional, Jackson consideraría que los tipos de Joda son solo POJO, y utilizaría getters / setters. Pero el módulo de Joda usa representaciones más compactas (cadenas, matrices). Entonces, lo que puede estar sucediendo es que el lado de la serialización no está utilizando el módulo Joda; Y la deserialización es.
El problema clave aquí es que Spring está convirtiendo JodaTime de una manera diferente, por ejemplo, en Jersey.
Esto es lo que tuve que hacer en mi 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>
Aquí puede encontrar el no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean de la biblioteca java-json-client
Para resolver un problema similar hice lo siguiente,
Descargué jackson-datatype-joda-2.2.1.jar de http://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-joda/2.2.1 si está utilizando maven, la definición de dependencia es ahí también.
Luego agregué una anotación para cada campo LocalDate en mi aplicación de la siguiente manera:
@JsonDeserialize(using=LocalDateDeserializer.class)
private LocalDate releasedDate;
Las importaciones se ven así:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer;
Y el problema desapareció.
¡Espero que esto ayude!
debe utilizar tanto la serialización como la deserialización para joda-time; contra esos campos que intenta guardar y recuperar.
Al hacer esto, le daremos a Jackson responsabilidades secundarias (java a mongo / json y mongo / json a conversiones de java).
Código de muestra:
@JsonDeserialize(using= LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
LocalDate dateFieldToBeConverted
Y estas son las importaciones:
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
Después de hacer esto, las consultas sencillas de guardar y buscar un único en mongo (a través de las clases de repositorio de Java) funcionarán sin ningún problema. Espero que esto ayude.