2012-11-27 6 views
16

v2.1.1 deserialisieren, joda module.Kann nicht Instanz von org.joda.time.DateTime oder LOCALDATE aus START_OBJECT Token

ich eine JSON-Datei zu einem pojo in einem Komponententest umwandeln kann objectMapper.readValue (Datei, pojo. Klasse);

Wenn jedoch ein Feder RESTTemplate Client die default json converter ruft eine input mit dem Domain-Objekt mit Joda Typen (Datetime oder LOCALDATE) zu konvertieren, erzeugt er einen Fehler: 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: 

gleiche Problem tritt bei LOCALDATE

 
com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: expected JSON Array, String or Number 
at Source: [email protected]; 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) 
.... 

Warum ist die Call-Kette eine START_OBJECT in einem Fall und START_ARRAY in den anderen vorbei?

+0

hast du es geschafft, das zu beheben? Ich habe das gleiche Problem mit der Deserialisierung in Lift – Adrian

Antwort

19

Um ein ähnliches Problem zu lösen ich folgendes tat,

ich heruntergeladen jackson-Datentyp-joda-2.2.1.jar von http://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-joda/2.2.1 wenn Sie Maven die Abhängigkeitsdefinition auch dort verwendet werden, ist.

dann habe ich eine Anmerkung für jedes Feld LOCALDATE in meiner app wie folgt:

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

die Einfuhren wie folgt aussehen:

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

Und das Problem verschwunden.

Hoffe, das hilft!

+0

Welche Version von Joda-Zeit benutzt du hier? Und ist es die gleiche Lösung für DateTime? z.B. '@JsonDeserialize (using = DateTimeDeserializer.class)' –

+0

die Version für joda-time ist 2.3 und in Bezug auf die andere Frage glaube ich, ich habe ein paar von denen ausprobiert, so denke ich, es sollte auch für diese arbeiten – drginm

5

Ich denke, das hat mit etwas Diskrepanz zwischen Serializer und Deserializer zu tun; so dass man das andere produziert (ich denke, Joda Modul schreibt tatsächlich ein Array von Ints, wenn registriert). Dies liegt höchstwahrscheinlich daran, dass entweder Deserializer- oder Serializer-Registrierung fehlt.

In der Standardeinstellung würde Jackson Jado-Typen ohne zusätzliche Behandlung als POJOs betrachten und Getter/Setter verwenden. Das Joda-Modul verwendet jedoch kompaktere Darstellungen (Strings, Arrays). Was also passiert, ist, dass die Serialisierungsseite kein Joda-Modul verwendet; und Deserialisierung ist.

+0

In meinem Szenario war es in der Tat ein Serialisierungsproblem. Spring MVC/Integration serialisiert das Array des JodaType-Objekts. Annotationen mit '@JsonSerialize (using = DateTimeSerializer.class)' funktionierte gut, da Spring automatisch die Jackson-Module hinzufügt, wenn sie sich im Klassenpfad befinden, daher war die Deserialisierung mit Anmerkungen nicht erforderlich. –

0

Das Schlüsselproblem hier ist, dass Spring JodaTime auf eine andere Weise als zum Beispiel Jersey konvertiert.

Dies ist, was ich in meinem app-servlet.xml zu tun hatte:

<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> 

Hier können Sie die no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean aus der java-json-client Bibliothek

3

sollten Sie verwenden sowohl die Serialisierung und Deserialisierung für joda-Zeit finden ; gegen die Felder, die Sie speichern und abrufen möchten.
Indem wir dies tun, werden wir beide Seiten Verantwortung zu jackson (java zu mongo/json und mongo/json zu java conversions) geben.

Beispielcode:

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

und diese sind die Importe:

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 

Nachdem Sie das getan, einfach speichern und FindOne Abfragen auf Mongo (durch Java-Repo-Klassen) werden ohne Probleme arbeiten. Hoffe das hilft.

Verwandte Themen