2012-11-27 9 views
16

v2.1.1, joda module.Non può deserializzare istanza di org.joda.time.DateTime o LocalDate fuori START_OBJECT gettone

posso convertire un file JSON per un POJO in una prova di unità utilizzando objectMapper.readValue (file, pojo .class);

Tuttavia, quando un client Primavera RESTTemplate invoca il default json converter di convertire un inputStream contenente l'oggetto dominio con tipi Joda (datetime o LocalDate), si genera un errore: 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: [email protected]; 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: 

Lo stesso problema si verifica con LocalDate

Perché la catena di chiamate passa un START_OBJECT in un caso e START_ARRAY nell'altro?

+0

hai risolto il problema? Sto riscontrando lo stesso problema con la deserializzazione in Lift – Adrian

risposta

19

per risolvere un problema simile che ho fatto quanto segue,

Ho scaricato jackson-tipo di dato-Joda-2.2.1.jar da http://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-joda/2.2.1 se si utilizza Maven la definizione dipendenza è anche lì.

poi ho aggiunto un'annotazione per ogni campo LocalDate nella mia app come segue:

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

importazioni simile a questa:

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

E il problema scomparve.

Spero che questo aiuti!

+0

quale versione di joda-time stai usando qui? Ed è la stessa soluzione per DateTime? per esempio. '@JsonDeserialize (using = DateTimeDeserializer.class)' –

+0

la versione per joda-time è 2.3 e per quanto riguarda l'altra domanda credo di aver provato un paio di quelli quindi penso che dovrebbe funzionare anche per quello – drginm

5

Penso che questo abbia a che fare con qualche discrepanza tra serializzatore e deserializzatore; così che uno produce l'altro (penso che il modulo Joda scriva effettivamente una serie di ints, quando registrato). Probabilmente si verifica perché manca la deserializzazione o la registrazione con il serializzatore.

Per impostazione predefinita, senza alcuna gestione aggiuntiva, Jackson considererebbe i tipi Joda solo POJO e utilizzerà getter/setter. Ma il modulo Joda usa rappresentazioni più compatte (stringhe, matrici). Quindi quello che potrebbe succedere è che il lato di serializzazione non sta usando il modulo Joda; e la deserializzazione è.

+0

Nel mio scenario, si trattava effettivamente di un problema di serializzazione. Spring MVC/Integration stava serializzando la matrice dell'oggetto JodaType. Annotando con '@JsonSerialize (using = DateTimeSerializer.class)' ha funzionato bene in quanto Spring aggiunge automaticamente i moduli Jackson se si trovano sul classpath, quindi la deserializzazione con le annotazioni non era richiesta. –

0

Il problema chiave qui è che Spring sta convertendo JodaTime in un modo diverso, ad esempio Jersey.

questo è quello che dovevo fare nella mia 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> 

Qui potete trovare il no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean dalla libreria java-json-client

3

si dovrebbe utilizzare sia serializzazione e deserializzazione per joda-time ; contro quei campi che stai cercando di salvare e recuperare.
Così facendo, daremo entrambe le responsabilità a Jackson (da java a mongo/json e mongo/json a java).

codice di esempio:

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

e queste sono le importazioni:

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 

dopo aver fatto questo, semplice salvare e query FindOne su Mongo (attraverso le classi Java pronti contro termine) funzioneranno senza problemi. Spero che questo ti aiuti.

Problemi correlati