2013-01-16 15 views
7

Ich muss neue Eigenschaft zu einem Objekt hinzufügen, beim Serialisieren zu JSON. Der Wert für die Eigenschaft wird zur Laufzeit berechnet und ist im Objekt nicht vorhanden. Auch das gleiche Objekt kann für die Erstellung von verschiedenen JSON mit verschiedenen Feldern verwendet werden (eine Basisklasse mit Unterklassen, aber ich möchte keine nur für die JSON-Generierung erstellen).Jackson :: Hinzufügen von zusätzlichen Feldern zu einem Objekt in Serialisierung

Was ist der beste Weg, dies zu tun, was nicht die Erstellung von benutzerdefinierten Serializer-Klasse, die Serialisierung von ganzen Satz von Objektfeldern kümmern wird beteiligt? Oder vielleicht ist es möglich, einige "grundlegende" Serializer zu erben, und nehmen Sie einfach seine Ausgabe und fügen Sie neue Feld irgendwie hinzu?

Ich habe über mixins gelernt, und es sieht so aus, als ob es möglich ist, einige Felder umzubenennen/auszublenden, es scheint jedoch nicht möglich zu sein, einen zusätzlichen hinzuzufügen.

Antwort

8

Können Sie nicht einfach eine Methode in der Werteklasse hinzufügen? Beachten Sie, dass es nicht öffentlich sein muss oder Getter-Namenskonventionen verwenden muss. Sie könnte so etwas wie:

JsonNode tree = mapper.valueToTree(value); 

und ändern Sie es durch Hinzufügen von Eigenschaften usw.

+0

wird die Verantwortung serialisiert dies nicht funktioniert, wenn das zusätzliche Feld nicht Teil des Objekts ist. Z.B. die URL eines Objekts ... Es ist nicht die Aufgabe des Objekts, seine eigene Adresse zu kennen, es ist der Job einer höheren Ebene. – cdeszaq

+0

Ganz, aber warum wird es dann in demselben JSON-Objekt serialisiert? Dies klingt nach einem möglicherweise schlechten Design für JSON-Nutzdaten. Obwohl JSON das Problem hat, dass es keine einfache Trennung zwischen Daten und Metadaten gibt (man kann Namenskonventionen finden) – StaxMan

+0

Die interne Objektdarstellung ist nicht die gleiche wie die externe Ressourcendarstellung (die sich je nach Akzeptiertem Header ändern muss) . URL oder Adresse, bei der eine Ressource lebt, können sich ändern und liegen nicht in der Verantwortung des internen Objekts, sondern der Routen oder einer anderen höheren Ebene. – cdeszaq

1

Eine Option ist ein Feld hinzuzufügen:

public class MyStuff { 
    // ... the usual fields, getters and/or setters 

    @JsonProperty("sum") // or whatever name you need in JSON 
    private int calculateSumForJSON() { 
     return 42; // calculate somehow 
    } 
} 

Ansonsten POJO in JSON Baum Wert, den Sie konvertieren könnte für diese Eigenschaft und setzen Sie sie auf das Objekt vor dem Schreiben in JSON. Eine zweite Option, wenn die Eigenschaft kann von anderen Objekteigenschaften berechnet werden könnten Sie einfach einen Getter für sie hinzufügen, zum Beispiel:

public String getFullName() { 
    return getFirstName() + " " + getLastName(); 
} 

Und obwohl es keine passenden Feld ist Jackson wird diese Getter automatisch aufrufen, während die JSON Schreiben und es erscheint als fullName in der JSON-Ausgabe. Wenn das nicht eine dritte Option arbeitet, ist das Objekt auf eine Karte zu konvertieren und dann zu manipulieren aber Sie brauchen:

ObjectMapper mapper //..... 
MyObject o //..... 
long specialValue //..... 
Map<String, Object> map = mapper.convertValue(o, new TypeReference<Map<String, Object>>() { }); 
map.put("specialValue", specialValue); 

Sie ist Frage nicht erwähnt unmarshalling aber wenn Sie brauchen das auch tun dann würde die erste Option gut funktionieren, aber die zweiten beiden müssten etwas optimiert werden.

Und wie für verschiedene Bereiche des gleichen Objekts schreibt es wie ein Job klingt für @JsonView

+0

Das "Convert to a map" -Objekt klingt, als ob es in Ordnung wäre, aber es scheint ein bisschen klobig. Die Option "Feld hinzufügen" funktioniert nicht, wenn das zusätzliche Feld nicht Teil des serialisierten Objekts ist. Z.B. die URL eines Objekts ... Es ist nicht die Aufgabe des Objekts, seine eigene Adresse zu kennen, es ist der Job einer höheren Ebene. – cdeszaq

Verwandte Themen