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
}
}
}