2016-10-10 1 views
0

Deserialisieren habe ich ein benutzerdefiniertes Objekt, das eine generische Art verwendet:ein Objekt mit einem generischen Typ mit Jackson

class MyObject <T> { 
    int x; 
    String y; 
    T customObject; 
} 

I jackson bin mit dem Objekt serialisiert und serialisiert wird. Beim Deserialisieren des Objekts wollte ich wissen, was genau ich für das Typfeld weitergeben soll.

Sollte es Option 1 oder 2 sein?

ObjectMapper mapper = new ObjectMapper(); 
MyObject obj1 = objectMapper.readValue(jacksonString, MyObject.class); //option 1 

MyObject obj1 = objectMapper.readValue(jacksonString, MyObject<T>.class); //option 2 

Ich bin verwirrt, wenn dies auch der richtige Ansatz ist.

+0

Es müßte Option 2 sein, da die Deserializer nicht wissen, welche Klasse für customObject sonst zu verwenden. Anstelle von T müssen Sie explizit deklarieren, welche Klasse für den generischen verwendet wird (dh 'objectMapper.readValue (jacksonString, MyObject .class')) –

+0

Da Java-Generika Typ löschen verwenden,' MyObject.class' und 'MyObject .class' ist das gleiche Klassenobjekt –

+0

Nun, Option 2 nicht kompilieren, so ist es _definitely_ nicht, dass die meisten Sie bei der Kompilierung bekommen können, ist 'MyObject obj1 = ... MyObject.class)..' Nach das musst du unkontrollierte Umwandlungen machen; Wahrscheinlich möchten Sie manuell überprüfen, ob "customObject" vom erwarteten Typ ist, bevor Sie diese Umwandlung durchführen. – yshavit

Antwort

0

Ich kann nicht Ihre erklären Gson Fehler. Sie haben ein Problem, das in dem von Ihnen geposteten Code nicht ersichtlich ist.

Was, wie diese Arbeit mit Jackson zu machen, mit dem TypeReference wie erwähnt in Ihrem Kommentar ist die richtige Antwort. Das wird es jedoch nicht immer beheben. Sie haben eine Reihe von Optionen, einschließlich Jackson Annotationen und/oder Jackson "Mixins". Der einfachste Weg, dies zu beheben, besteht jedoch wahrscheinlich darin, Getter und Setter zu Ihren Klassen hinzuzufügen. Jackson wird Ihre Getter und Setter erkennen und Ihre Objekte entsprechend serialisieren und deserialisieren.

Der folgende Code ist janky in einer Reihe von Möglichkeiten, aber es funktioniert.

import com.fasterxml.jackson.core.type.TypeReference; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import java.io.IOException; 

public class App { 
    public static void main(final String[] args) throws IOException { 
     final MyType myType = new MyType(); 
     myType.setField1("blah"); 
     myType.setField2(311); 

     final MyObject<MyType> myObj = new MyObject<>(); 
     myObj.setX(10); 
     myObj.setY("why oh why"); 
     myObj.setCustomObject(myType); 

     final ObjectMapper mapper = new ObjectMapper(); 
     final String json = mapper.writeValueAsString(myObj); 
     System.out.println(json); 

     final TypeReference<MyObject<MyType>> typeRef = new TypeReference<MyObject<MyType>>() {}; 

     final MyObject<MyType> myObj2 = mapper.readValue(json, typeRef); 
     System.out.println("x: " + myObj2.getX()); 
     System.out.println("y: " + myObj2.getY()); 
     System.out.println("customObject:"); 
     System.out.println(" " + myObj2.getCustomObject().getField1()); 
     System.out.println(" " + myObj2.getCustomObject().getField2()); 
    } 

    public static class MyType { 
     private String field1; 
     private int field2; 

     public String getField1() { return field1; } 
     public void setField1(final String field1) { this.field1 = field1; } 

     public int getField2() { return field2; } 
     public void setField2(final int field2) { this.field2 = field2; } 
    } 

    public static class MyObject<T> { 
     private int x; 
     private String y; 
     private T customObject; 

     public int getX() { return x; } 
     public void setX(final int x) { this.x = x; } 

     public String getY() { return y; } 
     public void setY(final String y) { this.y = y; } 

     public T getCustomObject() { return customObject; } 
     public void setCustomObject(final T customObject) { this.customObject = customObject; } 
    } 
} 

Die Ausgabe von dieser ist:

{"x":10,"y":"why oh why","customObject":{"field1":"blah","field2":311}} 
x: 10 
y: why oh why 
customObject: 
    blah 
    311 
+0

hilfreich Dies ist definitiv gegossen werden kann. Ich möchte das mit meinem eigenen Anwendungsfall ausprobieren. Wird die Antwort akzeptieren, sobald ich es getestet habe. Aber vielen Dank! – chrisrhyno2003

+0

Benötige ich die Getter und Setter, selbst wenn ich das @Builder-Muster von Lombok verwende? – chrisrhyno2003

+0

Möglicherweise nicht. Ich habe keine Erfahrung mit Lombok, aber eine Google-Suche hat gezeigt, dass Leute Dinge tun, die sich anhören, als ob Sie etwas tun möchten. Zum Beispiel [diese Seite zum Erstellen von unveränderlichen Objekten mit Lombok und Jackson] (http://delta46.us/java-immutable-lombok/). Als eine Art des Stils vermeide ich im Allgemeinen, meine POJOs mit Jackson Annotationen zu verschmutzen, also würde ich versucht sein, dies mit [Jackson Mixins] zu versuchen (http://wiki.fasterxml.com/JacksonMixInAnnotations). –

Verwandte Themen