2017-08-08 5 views
1

Ich habe riesige JSON-Dokument und entsprechende Jaskon Modelle, die diesem JSON zugeordnet sind. In einigen Fällen ist es nicht möglich, das erforderliche JSON-Dokument mit allen Objekten zu erstellen, da einige Daten nicht vorhanden sind.Jackson: Serialize Null-Objekt als leer

zum Beispiel habe ich folgende Modelle:

class First { 

    private firstField; 
    private secondField; 
    etc... 
} 

class Second { 

    private firstField; 
    private secondField; 
    etc... 
} 

class General { 

    private First first; 
    private Second second; 
    etc... 
} 

Und es besteht die Möglichkeit, nur erste Instanz zu bevölkern:

In üblichen Fällen wird es so etwas wie dies serialisiert werden:

{ 
    "first":{ 
     "firstField":"some_value", 
     "secondField":"some_value" 
    }, 
    "second":null 
} 

Aber mein Ziel ist es, allgemeine Klasse so etwas zu serialisieren:

{ 
    "first":{ 
     "firstField":"some_value", 
     "secondField":"some_value" 
    }, 
    "second":{ 
     "firstField":"null", 
     "secondField":"null" 
    } 
} 

Es ist möglich, dies mit erreichen folgenden Änderungen der allgemeinen Klasse, um ihre Mitglieder zu initialisieren standardmäßig mit Standardkonstruktoren:

class General { 

     private First first = new First(); 
     private Second second = new Second() 
     etc... 
    } 

Aber dieser Ansatz führt dazu, dass zu viele Änderungen um bestehende Modelle und ich bin nicht sicher, dass es der beste Ansatz ist. Ist es möglich, einen benutzerdefinierten Serializer zu erstellen, der das selbst erledigt?

Herausgegeben nach https://stackoverflow.com/users/1898563/michael Vorschlag:

die Hauptidee Serializer Also, zu schaffen, die zu prüfen wären in der Lage, ob Instanz null ist und wenn es null ist, sollte es in der Lage sein, neue Instanz erstellen Standard verwenden Konstruktor, Hinweis: dieser Serializer sollte nicht auf spezifische Second Klasse basieren, sollte es mit jedem Objekt, das serialisiert werden wird, außer einfache Typen funktionieren.

Antwort

2

Ja, es ist möglich, einen benutzerdefinierten Serializer zu erstellen, der Reflektionen dazu verwendet. Sie können dies tun, indem Sie StdSerializer erweitern. Ihre Implementierung könnte etwa so aussehen:

public class NullSerializer<T> extends StdSerializer<T> { 

    public NullSerializer() { 
     this(null); 
    } 

    public NullSerializer(Class<T> t) { 
     super(t); 
    } 

    @Override 
    public void serialize(T item, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException, 
      IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException) 
    { 

     jgen.writeStartObject(); 

     // For all fields of the class you're serializing 
     for (final Field field : item.getClass().getDeclaredFields()) 
     { 
      field.setAccessible(true); 

      Object value = field.get(item); 

      // if the value is null, create a new instance 
      if (value == null) 
      { 
       value = field.getType().getConstructor().newInstance(); 
      } 

      // write it 
      jgen.writeObject(value); 
     } 

     jgen.writeEndObject(); 
    } 
} 

Dies beruht darauf, dass es für jedes der Felder einen öffentlichen Standardkonstruktor gibt. Möglicherweise möchten Sie einige der Ausnahmen abfangen, anstatt sie wie in der Signatur angegeben zu deklarieren.

Sie müssen diesen Serializer mit dem ObjectMapper registrieren. This article erklärt, wie man das macht.


Ich denke nicht, dass dies eine besonders elegante Lösung ist, aber es sollte Ihre Anforderungen erfüllen. Ich würde vermeiden, zuerst Nullfelder zu haben, aber vielleicht ist das in Ihrem Fall nicht möglich.

+0

Danke, für eine schnelle Antwort, wahrscheinlich war meine Frage nicht in angemessener Weise beschreiben, eigentlich die Hauptidee, Serialisierer zu haben, der in der Lage wäre, jedes Objekt außer einfachen Typen zu überprüfen, ob es null ist und ob es gleich null ist In der Lage, neue Objekte unter Verwendung von Standardkonstruktoren zu erstellen, so dass es nicht auf einem bestimmten zweiten Typ basieren sollte, sollte es in der Lage sein, mit jedem neuen Objekt zu arbeiten, das serialisiert wird. – fashuser

+0

Kein Problem. Nun, du musst deine Frage dann bearbeiten. – Michael

+0

getan, aktualisiert, wie Sie vorgeschlagen haben – fashuser

Verwandte Themen