Zum Verarbeiten von JSON-Dokumenten gibt es in der Java SE keine Standardklassen, sodass sich eine Reihe von Open-Source-Bibliotheken herausgeprägt haben; Jackson (http://tutego.de/go/jackson) gehört zu den populärsten Lösungen. 2013 wurde dann die JSR 353, „Java API for JSON Processing“ verabschiedet, die Teil der Java EE 7 ist.
Wir können die JSON-API in unseren Java SE-Programmen nutzen, müssen dafür aber Java-Archive im Klassenpfad einbinden. Die Referenzimplementierung befindet sich unter https://javaee.github.io/jsonp/. Am Einfachsten haben es Maven-Nutzer, sie binden in ihre POM folgende Abhängigkeiten ein:
<dependency> <groupId>javax.json</groupId> <artifactId>javax.json-api</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.json</artifactId> <version>1.1</version> </dependency>
Aufbauen von JSON-Objekten, Formatieren und Parsen
Der Typ JsonObject ist in der API zentral, denn er definiert ein hierarchisches Model mit den Schlüssel-Wertepaaren eines JSON-Objekts. Um ein JsonObject aufzubauen können wir über den JsonObjectBuilder gehen, oder wir lassen den Parser JsonReader aus einer String-Repräsentation ein JsonObject erzeugen. Zum formatierten Schreiben in einen Ausgabestrom können wir einen einfachen JsonWriter von der Json-Klasse holen – es geht aber noch einfacher über toString() – oder über die JsonWriterFactory arbeiten, falls wir eine hübsche eingerückte Ausgabe wünschen. Ein Beispiel:
Point p = new Point( 10, 20 ); JsonObjectBuilder objBuilder = Json.createObjectBuilder() .add( "x", p.x ) .add( "y", p.y ); JsonObject jsonObj = objBuilder.build(); System.out.println( jsonObj ); // {"x":10,"y":20} Json.createWriter( System.out ).write( jsonObj ); // {"x":10,"y":20} Map<String, Boolean> config = new HashMap<>(); config.put( JsonGenerator.PRETTY_PRINTING, true ); JsonWriterFactory writerFactory = Json.createWriterFactory( config ); StringWriter out = new StringWriter(); writerFactory.createWriter( out ).write( jsonObj ); System.out.println( out ); // {\n "x": 10, ... JsonReader reader = Json.createReader( new StringReader( out.toString() ) ); System.out.println( reader.readObject().getInt( "x" ) ); // 10
Soll der assoziierte Wert ein Array sein, so wird dieser mit Json.createArrayBuilder().add(..).add(..) aufgebaut und gefüllt.
JSON-Streaming API
So wie es für XML eine Pull-API gibt, existiert diese auch für JSON-Dokumente; das ist von Vorteil, wenn die Daten sehr groß sind. Ein Beispiel zeigt das sehr gut:
URL url = new URL( "https://data.cityofnewyork.us/api/views/25th-nujf/rows.json?accessType=DOWNLOAD" ); try ( JsonParser parser = Json.createParser( url.openStream() ) ) { while ( parser.hasNext() ) { switch ( parser.next() ) { case KEY_NAME: case VALUE_STRING: System.out.println( parser.getString() ); break; case VALUE_NUMBER: System.out.println( parser.getBigDecimal() ); break; case VALUE_TRUE: System.out.println( true ); break; case VALUE_FALSE: System.out.println( false ); break; case VALUE_NULL: case START_ARRAY: case END_ARRAY: case START_OBJECT: case END_OBJECT: // Ignore } } }