Skip to content

JSON vs. xstream

Das diverse Tools oder Bibliotheken sich gerne nicht so gut verstehen ist nichts neues. Aber manchmal fällt schwer, zu sagen, welches davon jetzt Mist baut.
Aber von vorne: Für ein neues Projekt werden Metadaten in XML angeliefert, die in einer Datenbank gespeichert werden sollen. Nun ist das auseinander Pflücken von XML-Files ziemlich mühselig. Ganz zu schweigen davon, dass die Daten in einem anderen Schritt wieder zusammen gesetzt werden müssen.
Es bot sich also eine elegante Lösung an: die XML-Files mit xstream in ein POJO de-serialisieren, validieren und ebenfalls mit xstream in eine JSON-Repräsentation umwandeln - und ab damit in die CouchDB!
Das funktioniert auch ganz wunderbar. Auch der umgekehrte Weg - den JSON-String wieder in ein POJO de-serialisieren - klappt ohne Probleme.

Die Probleme fangen erst an, wenn man mit einer entsprechenden Library an die CouchDB geht, und ein org.json.JSONObject zurück bekommt. Denn in dem daraus de-serialisiertem POJO, war auf einmal in einer darin enthaltenen Map systematisch key und value vertauscht. Die CouchDB war als Problemquelle sehr schnell ausgeschlossen, denn mit dem von ihr zurück gelieferten JSON-String trat das Problem nicht auf. Der String jedoch, der von org.json.JSONObject.toString() geliefert wurde, unterschied sich merklich von dem, was CouchDB lieferte.

Nun ist es so, dass xstream eine Map, wie zB "Map" folgendermaßen als JSON serialisiert:
"mapObjectName": {
   "entry": [
      { 
         "string": "theKey",
         "CustomObject": { "someField": "fieldValue" }
      }
   ]
}


Von org.json.JSONObject.toString() wird aber folgendes ausgegeben:
"mapObjectName": {
   "entry": [
      { 
         "CustomObject": { "someField": "fieldValue" }
         "string": "theKey",
      }
   ]
}

Dafür gibt es zwei Gründe: zum einen schreibt JSON nicht vor, das die Daten in der richtigen Reihenfolge sein müssen. Zum anderen, versucht es das JSONObject auch gar nicht erst - das Problem tritt nämlich nicht erst beim ausgeben der Daten auf, sondern liegt bereits darin begründet, wie diese intern gespeichert werden.

Und das ist genau die Stelle, an der es schwer fällt einen schuldigen zu finden. Ist xstream schuld (bzw. der verwendete Driver für JSON), weil über die JSON-spec hinaus darauf vertraut, dass die Daten immer in der richtigen Reihenfolge sind? Könnte xstream ein Map überhaupt anders serialisieren, um das zu umgehen? Oder macht das "Feature" von JSON, Daten eben explizit unsortiert zu behandeln, mehr Probleme als es löst?

Da ich weder die Zeit noch die Lust hatte, diesen Fragen auf den Grund zu gehen, und es das Problem ohnehin nicht gelöst hätte, hab ich einfach bei der Implementierung angesetzt. Da die Java-library freie Software ist, war das die einfachste Lösung.
Es musste nur in zwei Konstuktoren von org.json.JSONOBject folgende Zeile geändert werden:
Von
this.map = new HashMap();

Zu
this.map = new LinkedHashMap();


...das "import java.util.LinkedHashMap;" fügt eine gute IDE automatisch ein ;-)

Trackbacks

Keine Trackbacks

Kommentare

Ansicht der Kommentare: Linear | Verschachtelt

Noch keine Kommentare

Kommentar schreiben

Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.
Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.

Um maschinelle und automatische Übertragung von Spamkommentaren zu verhindern, bitte die Zeichenfolge im dargestellten Bild in der Eingabemaske eintragen. Nur wenn die Zeichenfolge richtig eingegeben wurde, kann der Kommentar angenommen werden. Bitte beachten Sie, dass Ihr Browser Cookies unterstützen muss, um dieses Verfahren anzuwenden.
CAPTCHA

Formular-Optionen

Kommentare werden erst nach redaktioneller Prüfung freigeschaltet!