2016-04-22 19 views
2

Lassen Sie uns sagen, dass wir JSON haben folgende,Deserialisieren ausgewählte Eigenschaftsnamen nur (Jackson)

{ 
    "id": "imgsId1", 
    "type": "Fruits", 
    "name": "Tropical", 
    "image": 
    { 
     "url": "images/img1.jpg", 
     "width": 300, 
     "height": 300 
    }, 
    "thumbnail": 
    { 
     "url": "images/thumbnails/img11.jpg", 
     "width": 50, 
     "height": 50 
    } 
} 

Und in Java-Klasse haben wir alle Felder mit über JSON entsprechen.

Die Liste der zu deserialisierenden Felder hängt von dem jeweiligen Kunden ab, der die Informationen sendet.

Zum Beispiel für Kunden 1, wollen wir nur folgende Werte zurück zu lesen, (und andere Eigenschaften überspringen sogar in JSON falls vorhanden)

String[] propertiesToFilter1 = {"type","image.url"}; 

für Kunden 2 Zum Beispiel wollen wir wieder lesen folgende Werte, (skip und andere Eigenschaften, auch wenn in JSON bereitgestellt)

String[] propertiesToFilter2 = {"type","image.url", "image.width"}; 

wenn Deserialisieren JSON Jackson verwendet wird, ist es möglich, oberhalb Array bereitzustellen, die w umfasst hich Felder müssen deserialisiert werden,

ImageInfo obj1 = (ImageInfo)objectMapper.readValue(jsonStr, ImageInfo.class); 

Update:

On auf Netto-Forschung, sah ich, dass eine der Optionen, über

könnten mit
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("filterName1", 
        SimpleBeanPropertyFilter.serializeAllExcept(propertiesToFilter1)); 

objectMapper.setFilters(filterProvider); 

Aber ich denke, das ist gut, wenn wir dasselbe "filterName1" für mehrere Kunden weiterverwenden wollen.

In diesem Szenario ist es ein wenig anders, weil wir eine Liste von Feldern anpassen, die jeder Kunde aktualisieren kann. So hat jeder Kunde eine andere Liste von JSON-Feldern, die er in verschiedenen Klassen aktualisieren kann.

Wenn wir beginnen, verschiedene Filternamen für jeden Kunden zu definieren, wird es eine lange Liste sein, und die Suche hat Auswirkungen auf die Leistung.

So suchte nach Lösung, wo ich Liste der Felder überprüfen können, die zur Laufzeit verarbeitet werden, wenn zurück Objekt mit objectMapper.readValue() -Methode.

Update 2 (25. April 2016):

durch andere Jackson Fragen gehen, sah eine ähnliche Frage hier

Jackson Dynamic filtering of properties during deserialization

den Ansatz unten aufgeführten Verwendung von benutzerdefinierten „static ObjectMapper Schaffung "Das Problem bei diesem Ansatz ist, dass wir die Reflection-API mehrmals ausführen.

  • Zum ersten Mal Jackson Parser bevölkern alle Felder mit Reflection-API, wenn Deserialisieren JSON Java Object

  • Beim zweiten Mal, da wir nicht alle Felder übernehmen können, die von Jackson Parser bevölkert wurden, für Daten in ein anderes Objekt auffüllen, müssen wir erneut durch die Reflection-API laufen, um ein anderes Objekt zu füllen.

Dies könnte zu viel Overhead führen.

Mit dem Ansatz in der oben angegebenen Link definiert, ich denke, mit "BeanDeserializerModifier" scheint der beste Ansatz zu sein. Nun ist die Frage, da wir auch den Factory-basierten Ansatz verwenden, um ObjectMapper zu initialisieren, wollen wir nicht alle Arrays für verschiedene Kunden hart codieren.

Wollte prüfen, ob es möglich ist, das Array String [] mit einer Liste von Eigenschaften zu versehen, die zur Laufzeit in "BeanDeserializerModifier" berücksichtigt werden sollen?

etwas ähnliches,

String[] propertiesToFilter2 = {"type","image.url", "image.width"}; 

BeanDeserializerModifier curBeanDeserializerModifier = 
      getBeanDeserializerModifierInstance(); 

curBeanDeserializerModifier.setPropertiesToConsider(propertiesToFilter2); 

Dank

+0

Wie wissen Sie, für welche Kunden Sie Sachen deserialisieren haben und nicht, wenn? – Patrick

+0

Diese JSON-Datei konnte entweder per Web (Form POST) oder per FTP empfangen werden. Für alle Kunden verwenden wir dieselbe Java-Klassendatei. – mike39

Antwort

0
+0

Danke für die Antwort. @JsonIgnoreProperties ({"pw", "E-Mail", "Name", "Geräte", "lastModified", "erstellt"}) würde funktionieren, wenn ich diese Felder für Dateien von allen Kunden berücksichtigen möchte. ** Das Szenario hier ist für verschiedene Kunden, die wir anpassen möchten, welche Felder wir berücksichtigen möchten **. – mike39

+0

Es gibt einen Unterschied zwischen den verschiedenen Client in den Eingabedaten oder keine –

0

Ich bin nicht sicher, ob es eine Möglichkeit ist, die Deserialisierung dynamisch zu konfigurieren mit Anmerkungen. Ich würde vorschlagen, eine Klasse mit einer static ObjectMapper zu erstellen. In dieser Klasse können Sie verschiedene Implementierungen der Deserialisierung erstellen. Die Geschäftslogik Ihrer Anwendung sollte dann entscheiden, welche Implementierung für welchen Kunden verwendet werden soll. Innerhalb Ihrer verschiedenen Implementierungen können Sie die ObjectMapper wie Sie es mit Anmerkungen konfigurieren.

Eine zweite Lösung kann sein, den vollen json für jeden Kunden zu deserialisieren und die Geschäftslogik entscheiden zu lassen, welche Felder/Objekte des Pojo verwendet werden. Dies erfordert auch eine Implementierung in Ihrer Anwendung.

Der Vorteil der Implementierung der Konfiguration in der Geschäftslogik besteht darin, dass Sie saubereren Code und einen Ort haben, an dem Ihre Konfiguration für jeden Kunden vorgenommen wird.


static ObjectMapper information

+0

Bitte überprüfen Sie meine aktualisierten Kommentare. Dies hat Auswirkungen auf die Leistung, da wir die Java Reflection API mehrmals durchlaufen müssen. – mike39

+0

@ mike39 Am Ende müssen Sie den 'BeanDeserializerModifier' in Ihrem' objectMapper' registrieren, um ihn zu benutzen. Oder ich liege falsch? – Patrick

Verwandte Themen