image
image

Dipl.-Inform. Michael Inden ist Oracle-zertifizierter Java-Entwickler für JDK 6. Nach seinem Studium in Oldenburg war er lange Zeit als Softwareentwickler und -architekt bei verschiedenen internationalen Firmen tätig.

Dabei hat er über 15 Jahre Erfahrung beim Entwurf objektorientierter Softwaresysteme gesammelt, an diversen Fortbildungen und an mehreren Java-One-Konferenzen in San Francisco teilgenommen. Sein besonderes Interesse gilt dem Design qualitativ hochwertiger Applikationen mit ergonomischen, grafischen Oberflächen sowie dem Coaching von Kollegen.

Image

Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:

www.dpunkt.de/plus

Der Java-Profi: Persistenzlösungen und REST-Services

Datenaustauschformate, Datenbankentwicklung und verteilte Anwendungen

Michael Inden

image

Michael Inden

michael_inden@hotmail.com

Lektorat: Dr. Michael Barabas

Fachgutachter: Torsten Horn

Copy-Editing: Ursula Zimpfer, Herrenberg

Satz: Michael Inden

Herstellung: Susanne Bröckelmann

Umschlaggestaltung: Helmut Kraus, www.exclam.de

Druck und Bindung: M.P. Media-Print Informationstechnologie GmbH, 33100 Paderborn

Bibliografische Information der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

ISBN:

Print  978-3-86490-374-8

PDF  978-3-86491-960-2

ePub  978-3-86491-961-9

mobi  978-3-86491-962-6

1. Auflage 2016

Copyright © 2016 dpunkt.verlag GmbH

Wieblinger Weg 17

69123 Heidelberg

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.

Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.

Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.

5 4 3 2 1 0

Inhaltsverzeichnis

1      Einstieg in XML und JSON

1.1    Basiswissen XML

1.1.1   Bestandteile und Aufbau eines XML-Dokuments

1.1.2   Validierung eines XML-Dokuments

1.2    XML-Verarbeitung mit JAXP

1.2.1   Einfaches Parsing mit SAX

1.2.2   Komplexere Parsing-Aufgaben mit SAX

1.2.3   Parsing mit DOM

1.2.4   Verarbeiten und Speichern mit DOM

1.2.5   StAX als Alternative zu SAX oder DOM?

1.2.6   SAX, StAX oder DOM?

1.2.7   XPath im Überblick

1.2.8   XSLT im Überblick

1.2.9   XMLEncoder und XMLDecoder im Überblick

1.3    XML-Verarbeitung mit JAXB

1.3.1   Schritt 1: Passende Java-Klassen erstellen

1.3.2   Schritt 2: Marshalling und Unmarshalling

1.3.3   JAXB: Stärken und Schwächen

1.4    JAXB und StAX in Kombination

1.4.1   Rekonstruktion von Objekten mit JAXB und StAX

1.4.2   Vergleich zu SAX, DOM und JAXB

1.4.3   On-the-Fly-Modifikation von Objekten

1.5    JSON – das bessere XML?

1.5.1   Crashkurs JSON

1.5.2   JSON mit Java verarbeiten

1.5.3   JSON vs. XML

1.6    Weiterführende Literatur

2      Einführung in Persistenz und relationale Datenbanken

2.1   Grundlagen zur Persistenz

2.1.1   Beschränkungen einfacher Persistenzlösungen

2.1.2   Modelle zur Persistierung von Objekten

2.1.3   Speicherung von Daten in relationalen Datenbanken

2.2   Abbildung zwischen Objekt- und Datenbankmodell

2.2.1   Abbildung von Referenzen

2.2.2   Abbildung von Assoziationen und Aggregationen

2.2.3   Abbildung von Vererbung

2.3   Das Datenbanksystem HSQLDB im Kurzüberblick

2.4   SQL-Grundlagen

2.4.1   DDL – Definition von Tabellen

2.4.2   DQL – Datenabfrage

2.4.3   DML – Datenmanipulation

2.5   Ausfallsicherheit und Replikation

2.6   Weiterführende Literatur

3      Persistenz mit JDBC

3.1   Datenbankzugriffe per JDBC

3.1.1   Schritte zur Abfrage von Datenbanken

3.1.2   Besonderheiten von ResultSet

3.1.3   Abfrage von Metadaten

3.1.4   Probleme bei der Ausführung von Statements

3.1.5   Das Interface PreparedStatement

3.1.6   Transaktionen in JDBC

3.2   Grundlagen zum ORM mit JDBC

3.2.1   Rekonstruktion von Objekten

3.2.2   Zugriffe mit einem Data Access Object (DAO)

3.3   Weiterführende Literatur

4      Persistenz mit JPA

4.1   Grundlagen zum ORM und zum JPA

4.2   Einführung in JPA an einem Beispiel

4.2.1   Definition persistenter Klassen

4.2.2   Die Konfigurationsdatei persistence.xml

4.2.3   Datenbankzugriffe per JPA in Java SE

4.2.4   Lebenszyklus von Entitäten (Entity Lifecycle)

4.2.5   Datenbankmodell

4.2.6   Vorteile der konfigurativen Persistenz

4.3   JPQL im Überblick

4.3.1   Syntax von JPQL

4.3.2   Besondere Arten von Queries

4.3.3   Abfragen mit JPQL ausführen

4.3.4   Typsichere Abfragen und das Criteria API

4.4   DAO-Funktionalität mit JPA

4.4.1   CRUD-Funktionalität

4.4.2   Einsatz des DAO

4.5   Fortgeschritteneres ORM mit JPA

4.5.1   Abbildung von Assoziationen

4.5.2   Abbildung von Vererbungshierarchien

4.5.3   Verarbeitung der Typen aus JSR-310: Date and Time

4.5.4   Bean Validation im Einsatz

4.6   Transaktionen und Locking

4.6.1   Isolationslevel und Effekte

4.6.2   Problemkontext

4.6.3   Optimistic Locking

4.7   Caching in JPA

4.8   Fazit

4.9   Weiterführende Literatur

5      NoSQL-Datenbanken am Beispiel von MongoDB

5.1   Einführung und Überblick

5.2   Einführung MongoDB

5.2.1   Analogie von CRUD (RDBMS) zu IFUR (MongoDB)

5.2.2   Komplexere Abfragen

5.2.3   MongoDB und Transaktionen

5.3   Ausfallsicherheit und Skalierbarkeit

5.3.1   Hintergrundwissen: Formen der Skalierung

5.3.2   Ausfallsicherheit und Replica Sets

5.3.3   Skalierung und Sharding

5.3.4   Anmerkungen zu Replica Sets und Sharding

5.4   MongoDB aus Java ansprechen

5.4.1   Einführendes Beispiel

5.4.2   Daten einfügen und auslesen

5.4.3   Verarbeitung komplexerer Daten

5.4.4   Einfaches JSON-basiertes Object/Document Mapping

5.4.5   Object/Document Mapping mit Spring Data MongoDB

5.5   Fazit

5.6   Weiterführende Literatur

6      REST-Services mit JAX-RS und Jersey

6.1   REST im Kurzüberblick

6.1.1   Einführendes Beispiel eines REST-Service

6.1.2   Zugriffe auf REST-Services

6.1.3   Unterstützung verschiedener Formate

6.1.4   Zugriffe auf REST-Services am Beispiel von MongoDB

6.2   Ein REST-Service mit CRUD-Funktionalität

6.2.1   MIME-Types und unterschiedliche Datenformate

6.2.2   HTTP-Kommandos und CRUD-Funktionalität

6.3   Tipps zum Design von REST-Interfaces

6.3.1   Varianten der Rückgabe und Error Handling bei REST

6.3.2   Wertübergabe als @QueryParam oder @PathParam

6.3.3   Paging bei GET

6.4   Fortgeschrittene Themen

6.4.1   Einsatz von Request- und Response-Filtern

6.4.2   Security im Kontext von REST

6.4.3   Testen mit restfuse

6.5   Fazit

6.6   Weiterführende Literatur

7      Entwurf einer Beispielapplikation

7.1   Iteration 0: Ausgangsbasis

7.2   Iteration 1: Zentrale Verwaltung von Highscores

7.3   Iteration 2: Verwaltung von XML

7.4   Iteration 3: Bereitstellen als REST-Service

7.5   Iteration 4: Web-GUI mit HTML und JavaScript

7.6   Iteration 5: Protokollierung von Aktionen mit MongoDB

7.7   Fazit zum Abschluss der Iterationen

A     Einführung Gradle

A.1   Projektstruktur für Maven und Gradle

A.2   Builds mit Gradle

B     Client-Server-Kommunikation und HTTP im Überblick

B.1   Client-Server-Kommunikation

B.2   Basiswissen HTTP

C     Grundlagenwissen HTML

C.1   Basiswissen HTML

C.1.1   HTML am Beispiel

C.1.2   Interaktivität und Formulare

D     Wissenswertes zu JavaScript

D.1   Grundlagen zur Sprache

D.2   Modifikation von HTML

D.3   JSON-Verarbeitung

D.4   REST-Services ansprechen

Literaturverzeichnis

Index

Vorwort

Zunächst einmal bedanke ich mich bei Ihnen, dass Sie sich für dieses Buch entschieden haben. Hierin finden Sie Informationen zu den Datenaustauschformaten XML und JSON sowie zum Zugriff auf Datenbanken mit JDBC und JPA als auch auf MongoDB. Darüber hinaus werden RESTful Webservices mit JAX-RS und Jersey behandelt. Diese für Unternehmensanwendungen wichtigen Themen möchte ich Ihnen anhand von praxisnahen Beispielen näherbringen. Dabei kommen die vielfältigen Neuerungen aus JDK 8 zum Einsatz, um die Beispiele prägnanter zu machen. Für einen fundierten Einstieg in Java 8 möchte ich Sie auf meine Bücher »Java 8 – Die Neuerungen« [9] oder alternativ »Der Weg zum Java-Profi« [8] verweisen. Beide können ergänzend, aber auch unabhängig von diesem Buch gelesen werden.

Motivation

Wenn Sie bereits komplexe Java-Applikationen für den Desktop-Bereich schreiben und sich vertraut mit der Sprache Java fühlen, dann sind Sie schon recht gut für das Berufsleben gerüstet. Allerdings kommen Sie dort früher oder später mit Datenbanken, dem Informationsaustausch basierend auf XML oder JSON und vermutlich auch verteilten Applikationen in Berührung. Darunter versteht man Programme, die auf mehreren JVMs (und gewöhnlich somit auf mehreren Rechnern) ausgeführt werden. Um zusammenzuarbeiten, müssen diese miteinander kommunizieren, wodurch ganz neue Herausforderungen, aber auch Möglichkeiten entstehen.

Vielleicht haben Sie sich bisher auf den Desktop-Bereich konzentriert und wollen nun per JDBC oder JPA mit einer Datenbank kommunizieren. Dann erhalten Sie in diesem Buch eine fundierte Einführung in die Persistenz mit Java, SQL, JDBC und JPA. Oftmals benötigen Sie aber weiteres Know-how, da die Programmanwender zunehmend anspruchsvoller werden: Neben einer gut bedienbaren Benutzeroberfläche kommt für viele Applikationen der Wunsch auf, deren Funktionalität – zumindest teilweise – auch im Netzwerk bereitzustellen. Dazu existieren vielfältige Technologien. In diesem Buch wollen wir uns auf die populären RESTful Webservices konzentrieren und mit der Programmierung einer sogenannten Client-Server-Applikation beschäftigen.

Wie Sie sehen, sind Unternehmensanwendungen ein spannendes, aber auch weitreichendes Feld, was deutlich mehr Anforderungen als reine Java-SE-Anwendungen an den Entwickler stellt. Dieses Buch gibt Ihnen einen fundierten Einstieg. Wie schon bei meinem Buch »Der Weg zum Java-Profi« war es auch diesmal mein Ziel, ein Buch zu schreiben, wie ich es mir selbst immer als Hilfe gewünscht habe, um mich auf die Herausforderungen und Aufgaben im Berufsleben vorzubereiten.

Wer sollte dieses Buch lesen?

Dieses Buch ist kein Buch für Programmierneulinge, sondern richtet sich an all diejenigen Leser, die solides Java-Know-how besitzen und ihren Horizont auf die interessante Welt der Unternehmensanwendungen erweitern wollen. Dazu werden die dafür benötigten Themen Datenaustauschformate (XML, JSON) sowie Datenbankentwicklung (RDBMS, SQL, JDBC, JPA und auch NoSQL-DBs mit MongoDB) sowie die Kommunikation in verteilten Applikationen mit REST-Webservices (JAX-RS) vorgestellt.

Dieses Buch richtet sich im Speziellen an zwei Zielgruppen:

  1. Zum einen sind dies engagierte Hobbyprogrammierer, Informatikstudenten und Berufseinsteiger, die Java als Sprache beherrschen und nun neugierig auf die zuvor genannten Themen sind.

  2. Zum anderen ist das Buch für erfahrene Softwareentwickler und -architekten gedacht, die ihr Wissen ergänzen oder auffrischen wollen.

Was soll mithilfe dieses Buchs gelernt werden?

Dieses Buch zeigt und erklärt einige wesentliche Themen, die bei der Realisierung von Unternehmensapplikationen von Bedeutung sind. Sollte ein Thema bei Ihnen besonderes Interesse wecken und Sie weitere Informationen wünschen, so finden sich in den meisten Kapiteln Hinweise auf weiterführende Literatur.

Zwar ist Literaturstudium hilfreich, aber nur durch Übung und Einsatz in der Praxis können wir unsere Fähigkeiten signifikant verbessern. Deshalb ermuntere ich Sie, die gezeigten Beispiele (zumindest teilweise) durchzuarbeiten. Manchmal werde ich bei der Lösung eines Problems bewusst zunächst einen Irrweg einschlagen, um anhand der anschließend vorgestellten Korrektur die Vorteile deutlicher herauszustellen. Mit dieser Darstellungsweise hoffe ich, Ihnen mögliche Fallstricke und Lösungen aufzeigen zu können.

Des Weiteren lege ich Wert darauf, auch den kleinen, scheinbar nicht ganz so wichtigen Dingen ausreichend Beachtung zu schenken. Zum Beispiel ist es von großem Nutzen, wenn Klassen, Methoden, Attribute usw. einen sinnvollen Namen tragen.

Auch auf der Ebene des Designs lässt sich einiges falsch machen. Die Komplexität in der zu modellierenden Fachlichkeit dient häufig als Ausrede für konfuse und verwirrende Lösungen. Beim professionellen Entwickeln sollte man aber viel Wert auf klares Design legen. Grundsätzlich sollte alles möglichst einfach und vor allem gut verständlich gehalten werden, sodass eine ausgereifte und wartbare Lösung entsteht.

Sourcecode und ausführbare Programme

Da der Fokus des Buchs auf dem praktischen Nutzen und der Vorbereitung auf das Berufsleben bzw. dessen besserer Meisterung liegt, werden praxisnahe Beispiele vorgestellt. Um den Rahmen des Buchs nicht zu sprengen, stellen die Listings häufig nur Ausschnitte aus lauffähigen Programmen dar – zum besseren Verständnis sind wichtige Passagen dort mitunter fett hervorgehoben. Die in den Listings abgebildeten Sourcecode-Fragmente stehen als kompilierbare und lauffähige Programme (Gradle-Tasks) auf der Webseite zu diesem Buch www.dpunkt.de/java-persistenz zum Download bereit. Der Programmname bzw. der Name des ausführbaren Gradle-Tasks wird in Kapitälchenschrift, etwa FIRSTSAXEXAMPLE, angegeben.

Neben dem Sourcecode befindet sich auf der Webseite ein Eclipse-Projekt, über das sich alle Programme ausführen lassen. Idealerweise nutzen Sie dazu Eclipse 4.5 oder neuer, weil diese Version der IDE bereits Java 8 unterstützt und die Beispiele dieses Buchs immer wieder auch Funktionalitäten aus JDK 8 nutzen.

Neben dem Eclipse-Projekt wird eine Datei build.gradle mitgeliefert, die den Ablauf des Builds für Gradle beschreibt. Dieses Build-Tool besitzt viele Vorzüge wie die kompakte und gut lesbare Notation und vereinfacht die Verwaltung von Abhängigkeiten enorm. Gradle wird im Anhang A einführend beschrieben. Als Grundlage für spätere Ergänzungen dient folgende Datei build.gradle, die JUnit als Abhängigkeit definiert und trotz der Kürze schon ein vollständiges Release als jar-Datei namens java-profi-db-rest.jar erzeugt:

apply plugin: 'java'
apply plugin: 'eclipse'

sourceCompatibility=1.8

// create special jar containing the starter app
jar
{
    baseName = "java-profi-db-rest"

    manifest
    {
        attributes ( "Main-Class" : "de.inden.starter.ApplicationStarter" )
    }
}

repositories
{
    mavenCentral()
}

dependencies
{
    testCompile 'junit:junit:4.11'

    // Weitere Abhängigkeiten hier eintragen
}

Aufbau dieses Buchs

Nachdem Sie nun einen groben Überblick über den Inhalt dieses Buchs haben, möchte ich die Themen der einzelnen Kapitel kurz vorstellen.

Kapitel 1 – Einstieg in XML und JSON

Weil proprietäre Formate beim Datenaustausch oftmals Probleme bereiten, spielt in heutigen Applikationen die standardisierte Darstellung von Daten eine immer größere Rolle. Kapitel 1 stellt die Datenaustauschformate XML und JSON vor, die die Interoperabilität zwischen verschiedenen Programmen erleichtern und sogar einen Austausch erlauben, wenn diese Programme in unterschiedlichen Programmiersprachen erstellt wurden.

Kapitel 2 – Einführung in Persistenz und relationale Datenbanken

Dieses Kapitel stellt wichtige Grundlagen zu Datenbanken und zu SQL vor. Insbesondere wird auch auf Möglichkeiten der Transformation von Objekten in entsprechende Repräsentationen in Datenbanken eingegangen. Dabei wird vor allem auch der sogenannte Impedance Mismatch, die Schwierigkeiten bei der Abbildung von Objekten auf Tabellen einer Datenbank, thematisiert.

Kapitel 3 – Persistenz mit JDBC

Wie man mit Java-Bordmitteln auf Datenbanken zugreifen kann, ist Thema von Kapitel 3. Zunächst betrachten wir JDBC als Basistechnologie und erstellen verschiedene Beispielapplikationen bis hin zum Mapping von Objekten in die Datenbank, dem sogenannten ORM (Object-Relational Mapping).

Kapitel 4 – Persistenz mit JPA

Das JPA (Java Persistence API) stellt eine Alternative zu JDBC dar und erleichtert die Realisierung von Persistenzlösungen mit Java, insbesondere das ORM. In Kapitel 4 werden zunächst Grundlagen besprochen und dann gezeigt, wie sich selbst komplexere Objektgraphen mithilfe von JPA persistieren lassen.

Kapitel 5 – NoSQL-Datenbanken am Beispiel von MongoDB

Neben relationalen Datenbanken gewinnen NoSQL-Datenbanken immer mehr an Bedeutung. Ein Vertreter ist MongoDB, das in Kapitel 5 behandelt wird. Neben einer Einführung in die Theorie und ersten Experimenten mit der Mongo Console schauen wir uns die Verarbeitung mit Java, im Speziellen unter Zuhilfenahme von Spring Data MongoDB, an.

Kapitel 6 – REST-Services mit JAX-RS und Jersey

Kapitel 6 stellt RESTful Webservices vor, die seit geraumer Zeit im praktischen Alltag immer wichtiger werden: Viele Systeme binden die Funktionalität anderer Systeme basierend auf REST ein. Nach einer Einführung in die Thematik zeige ich einige Varianten, wie sich die Funktionalität eigener Applikationen als RESTful Webservice bereitstellen lassen.

Kapitel 7 – Entwurf einer Beispielapplikation

Den Abschluss des Hauptteils dieses Buchs bildet ein Kapitel, in dem eine Beispielapplikation entwickelt wird, die eine Vielzahl der zuvor im Buch vorgestellten Technologien einsetzt. Wir folgen einer iterativ inkrementellen Vorgehensweise und sehen dabei, wie man Erweiterungen schrittweise geschickt in bestehende Applikationen integrieren kann.

Anhang A – Einführung Gradle

Anhang A liefert eine Einführung in das Build-Tool Gradle, mit dem die Beispiele dieses Buchs übersetzt wurden. Mit dem vermittelten Wissen können Sie dann auch kleinere eigene Projekte mit einem Build-System ausstatten.

Anhang B – Einführung Client-Server und HTTP

Im Anhang B erhalten Sie einen Einstieg in die Client-Server-Kommunikation und HTTP, weil beides für verteilte Applikationen und REST-Services von zentraler Bedeutung ist.

Anhang C – Grundlagenwissen HTML

HTML und XML sind wichtige Standards, deren Kenntnis einem Java-Entwickler immer mal wieder nützlich sein kann. In diesem Anhang werden verschiedene Grundlagen zu HTML so weit vorgestellt, wie diese für das Verständnis einiger Beispiele aus diesem Buch notwendig sind.

Anhang D – Grundlagenwissen JavaScript

Das in Kapitel 7 entwickelte Abschlussbeispiel verwendet mitunter etwas JavaScript, um ein interaktives Web-GUI mit Zugriffen auf REST-Services zu erstellen. Die dazu benötigten Grundlagen zur Sprache JavaScript werden in diesem Anhang behandelt.

Konventionen

Verwendete Zeichensätze

In diesem Buch gelten folgende Konventionen bezüglich der Schriftart: Neben der vorliegenden Schriftart werden wichtige Textpassagen kursiv oder kursiv und fett markiert. Englische Fachbegriffe werden eingedeutscht großgeschrieben, etwa Event Handling. Zusammensetzungen aus englischen und deutschen (oder eingedeutschten) Begriffen werden mit Bindestrich verbunden, z. B. Plugin-Manager. Namen von Programmen und Entwurfsmustern werden in KAPITÄLCHEN geschrieben. Listings mit Sourcecode sind in der Schrift courier gesetzt, um zu verdeutlichen, dass dies einen Ausschnitt aus einem Java-Programm darstellt. Auch im normalen Text wird für Klassen, Methoden, Konstanten und Parameter diese Schriftart genutzt.

Verwendete Klassen aus dem JDK

Werden Klassen des JDKs erstmalig im Text erwähnt, so wird deren voll qualifizierter Name, d. h. inklusive der Package-Struktur, angegeben: Die Klasse String würde dann einmal als java.lang.String notiert – alle weiteren Nennungen erfolgen dann ohne Angabe des Package-Namens. Diese Regelung erleichtert initial die Orientierung und ein Auffinden im JDK und zudem wird der nachfolgende Text nicht zu sehr aufgebläht. Die voll qualifizierte Angabe hilft insbesondere, da in den Listings eher selten import-Anweisungen abgebildet werden.

Im Text beschriebene Methodenaufrufe enthalten in der Regel die Typen der Übergabeparameter, etwa substring(int, int). Sind die Parameter in einem Kontext nicht entscheidend, wird mitunter auf deren Angabe aus Gründen der besseren Lesbarkeit verzichtet – das gilt ganz besonders für Methoden mit generischen Parametern.

Klassen- und Tabellennamen

Zur besseren Unterscheidbarkeit von Objekt- und Datenbankwelt werde ich für dieses Buch als Konvention deutsche Tabellen- und Spaltennamen verwenden. Zudem werden Tabellen im Plural benannt, z. B. Personen. Beides hilft, die in Englisch gehaltene Objektwelt leichter von der in Deutsch repräsentierten Datenbankwelt abzugrenzen.

Verwendete Abkürzungen

Im Buch verwende ich die in der nachfolgenden Tabelle aufgelisteten Abkürzungen. Weitere Abkürzungen werden im laufenden Text in Klammern nach ihrer ersten Definition aufgeführt und anschließend bei Bedarf genutzt.

Abkürzung

Bedeutung

API

Application Programming Interface

ASCII

American Standard Code for Information Interchange

DB

Datenbank

(G)UI

(Graphical) User Interface

IDE

Integrated Development Environment

JDBC

Java Database Connectivity

JDK

Java Development Kit

JLS

Java Language Specification

JPA

Java Persistence API

JRE

Java Runtime Environment

JSON

JavaScript Object Notation

JVM

Java Virtual Machine

XML

eXtensible Markup Language

Tipps und Hinweise aus der Praxis

Dieses Buch ist mit diversen Praxistipps gespickt. In diesen werden interessante Hintergrundinformationen präsentiert oder es wird auf Fallstricke hingewiesen.

Danksagung

Ein Fachbuch zu schreiben ist eine schöne, aber arbeitsreiche und langwierige Aufgabe. Alleine kann man eine solche Aufgabe kaum bewältigen. Daher möchte ich mich an dieser Stelle bei allen bedanken, die direkt oder indirekt zum Gelingen des Buchs beigetragen haben. Insbesondere konnte ich bei der Erstellung des Manuskripts auf ein starkes Team an Korrekturlesern zurückgreifen. Es ist hilfreich, von den unterschiedlichen Sichtweisen und Erfahrungen profitieren zu dürfen.

Zunächst einmal möchte ich mich bei Michael Kulla, der als Trainer für Java SE und Java EE bekannt ist, für sein Review vieler Kapitel und die fundierten Anmerkungen bedanken. Auch Tobias Trelle als MongoDB-Experte hat sein Know-how in das Kapitel zu NoSQL-Datenbanken eingebracht. Vielen Dank!

Merten Driemeyer, Dr. Clemens Gugenberger und Prof. Dr. Carsten Kern haben mit verschiedenen hilfreichen Anmerkungen zu einer Verbesserung beigetragen. Zudem hat Ralph Willenborg mal wieder ganz genau gelesen und so diverse Tippfehler gefunden. Vielen Dank dafür! Ein ganz besonderer Dank geht an Andreas Schöneck für die schnellen Rückmeldungen auch zu später Stunde mit wertvollen Hinweisen und Anregungen.

Schließlich möchte ich verschiedenen Kollegen meines Arbeitgebers Zühlke Engineering AG danken: Jeton Memeti, Joachim Prinzbach, Marius Reusch, Dr. Christoph Schmitz, Dr. Hendrik Schöneberg und Dr. Michael Springmann. Sie trugen durch ihre Kommentare zur Klarheit und Präzisierung bei.

Ebenso geht ein Dankeschön an das Team des dpunkt.verlags (Dr. Michael Barabas, Martin Wohlrab, Miriam Metsch und Birgit Bäuerlein) für die tolle Zusammenarbeit. Außerdem möchte ich mich bei Torsten Horn für die fundierte fachliche Durchsicht sowie bei Ursula Zimpfer für ihre Adleraugen beim Copy-Editing bedanken.

Abschließend geht ein lieber Dank an meine Frau Lilija für ihr Verständnis und die Unterstützung. Glücklicherweise musste sie beim Entstehen dieses Erweiterungsbandes einen weit weniger gestressten Autor ertragen, als dies früher bei der Erstellung meines Buchs »Der Weg zum Java-Profi« der Fall war.

Anregungen und Kritik

Trotz großer Sorgfalt und mehrfachen Korrekturlesens lassen sich missverständliche Formulierungen oder sogar Fehler leider nicht vollständig ausschließen. Falls Ihnen etwas Derartiges auffällt, so zögern Sie bitte nicht, mir dies mitzuteilen. Gerne nehme ich auch sonstige Anregungen oder Verbesserungsvorschläge entgegen. Kontaktieren Sie mich bitte per Mail unter:

mailto:michael_inden@hotmail.com

Zürich und Aachen, im April 2016

Michael Inden

1 Einstieg in XML und JSON

Oftmals müssen Programme gewisse Daten speichern oder untereinander austauschen. Dazu gibt es verschiedene Möglichkeiten. Während früher oft proprietäre Formate verwendet wurden, hat sich dies mittlerweile geändert. Vielfach setzt man nun auf Standards wie XML (eXtensible Markup Language) und neuerdings auch JSON (JavaScript Object Notation). Um dem Trend nach Standardisierung Rechnung zu tragen, beschäftigt sich dieses Kapitel mit der Verarbeitung von Dokumenten. Wir schauen auf XML und JSON und welche Vorzüge man durch deren Einsatz erzielt.

Zunächst einmal ist erwähnenswert, dass XML eine strukturierte, standardisierte und doch flexible Art der Darstellung und Verarbeitung von Informationen erlaubt. Hilfreich ist dabei vor allem, dass die Daten und die strukturierenden Elemente (nahezu) frei wählbar sind. Dabei werden spezielle Zeichenfolgen, sogenanntes Markup, verwendet. Man spricht bei XML deshalb auch von einer sogenannten Auszeichnungssprache (Markup Language). Ähnlich wie Sie es vielleicht von HTML kennen, existieren auch in XML spezielle Zeichenfolgen, die eine steuernde oder besondere Bedeutung tragen. Das erlaubt es, Daten nahezu selbstbeschreibend darzustellen.

XML spielt auch beim Datenaustausch zwischen Programmkomponenten oder Systemen eine wichtige Rolle. Das liegt insbesondere an der einfach zu verarbeitenden Darstellung als textbasiertes Format, das sich zudem problemlos über das Netzwerk übertragen lässt. Für die Auswertung gibt es vom W3C (World Wide Web Consortium) verschiedene Varianten, die eine Vielzahl an Frameworks hervorgebracht haben, sodass eine Verarbeitung von XML in gebräuchlichen Programmiersprachen sowie der Austausch zwischen unterschiedlichen Systemen und Programmen einfach möglich wird.

Nach dieser Motivation möchte ich Ihnen kurz darlegen, was dieses Kapitel beinhaltet. Zu Beginn gebe ich eine kurze Einführung in XML, um für diejenigen Leser, für die dieses Thema neu ist, eine gemeinsame Basis mit bereits erfahreneren Kollegen zu schaffen. Dabei lernen wir einige Grundbausteine eines XML-Dokuments kennen. Anschließend gehe ich kurz auf Möglichkeiten zur semantischen Beschreibung mithilfe von DTDs (Document Type Definition) sowie XSDs (XML Schema Definition) ein. Mit diesem Grundwissen wenden wir uns der Verarbeitung von XML mit verschiedenen Java-APIs zu. Wir betrachten SAX (Simple API for XML) und DOM (Document Object Model) sowie StAX (Streaming API for XML). Zum Auswerten von XMLbasierten Daten werfen wir abschließend einen Blick auf XPath und XSLT (eXtensible Stylesheet Language Transformations). Außerdem betrachten wir noch JAXB (Java Architecture for XML Binding) und abschließend JSON.

1.1 Basiswissen XML

Sowohl HTML als auch XML sind textuelle Repräsentationen von Daten. Während in HTML eine vordefinierte Menge an Auszeichnungselementen, sogenannten Tags, etwa body, head, ol und table existiert, sind im Gegensatz dazu die Tags in XML nicht fest vorgegeben, sondern frei wählbar. Dies ermöglicht eine flexible Beschreibung und Strukturierung der Daten.

Weil sich Erklärungen anhand eines konkreten Beispiels in der Regel leichter nachvollziehen lassen, werfen wir einen Blick auf ein einfaches XML-Dokument, das eine Menge von Personen wie folgt modelliert:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- Dies ist ein Kommentar: Die erste Zeile ist der Prolog -->

<!-- Hier folgen nun die eigentlichen Daten -->
<Personen>
    <Person vorname="Michael" name="Inden" alter="44"></Person>
    <Person vorname="Hans" name="Meyer" alter="32"></Person>

    <!-- Kurzschreibweise für leere Elemente / leer. d. h. keine Subelemente -->
    <Person vorname="Peter" name="Muster" alter="55" />
</Personen>

An diesem Beispiel erkennt man verschiedene Dinge: XML-Dokumente speichern ihre Daten in sogenannten Elementen, die ineinander geschachtelt sein können. Das alle anderen umschließende Element nennt sich Wurzelelement. Im Beispiel gibt es drei Subelemente Person unter dem Wurzelelement Personen. Es wäre aber auch problemlos möglich, weitere Hierarchieebenen – etwa eine Adresse unterhalb eines Person-Elements – wie folgt einzufügen:

<Person vorname="Hans" name="Meyer" alter="32">
    <!-- Verschachtelte Subelemente -->
    <Adresse>
        <Stadt PLZ="24106">Kiel</Stadt>
    </Adresse>
</Person>

Ergänzend zu den textuellen Angaben von Werten innerhalb von Elementen sowie durch deren Verschachtelung können Informationen in sogenannten Attributen hinterlegt werden, wie dies für die Attribute vorname, name und alter des Elements Person gezeigt ist. Zudem können XML-Dokumente auch Kommentare enthalten, die mit der Zeichenfolge <!-- eingeleitet und mit --> abgeschlossen werden.

Schaut man auf das gezeigte XML-Dokument, so erkennt man, dass jedes Element eine Start- und Endmarkierung, Start- und End-Tag genannt, besitzt. Ebenso wie bei HTML werden diese Tags in spitzen Klammern notiert. Gewöhnlich treten öffnendes und schließendes Tag paarweise auf, also in der Notation <Person> ... </Person>. Die dritte Angabe einer Person zeigt eine Kurzschreibweise, bei der das Element durch die Notation /> abgeschlossen werden kann, sofern in dem Element keine Subelemente vorhanden sind.

Wohlgeformte und valide XML-Dokumente

Ergänzend zu diesen ersten syntaktischen, wenig formalen Regeln sollten XML-Dokumente zwei Anforderungen erfüllen: Sie sollten wohlgeformt und valide sein. Wohlgeformt bedeutet, dass alle vom XML-Standard geforderten, später ausführlicher genannten Regeln zur Syntax eingehalten werden – etwa dass Elemente ein korrespondierendes Start- und End-Tag besitzen. Neben diesen syntaktischen Anforderungen können auch semantische Anforderungen an ein XML-Dokument aufgestellt werden, unter anderem, welche Tags gültige Elemente darstellen und wie diese miteinander kombiniert werden dürfen. Erfüllt ein XML-Dokument diese Regeln ebenfalls, so ist es nicht nur wohlgeformt, sondern im Hinblick auf diese Anforderungen auch valide.

Abgrenzung von XML zu anderen Formaten

Neben XML sind weitere Formen der Datenspeicherung bzw. -repräsentation denkbar, etwa die in Java integrierte Serialisierung oder eine Repräsentation als Comma Separated Values (CSV) bzw. das immer populärer werdende JSON. Zudem gibt es alternativ auch immer noch proprietäre Formate.

Welche Argumente sprechen für den Einsatz von XML, welche dagegen? Jedes Format besitzt seine spezifischen Stärken und Schwächen. Die Verständlichkeit und die Interoperabilität leiden bei proprietären Formaten – insbesondere weil diese nicht immer voll umfänglich dokumentiert sind. Gerade bei der Kommunikation zwischen verschiedenen Rechnern mit gegebenenfalls unterschiedlichen Betriebssystemen spielen Dinge wie die Byte-Reihenfolge (Big vs. Little Endian) sowie Zeichensatzcodierungen und verschiedene Zeilenumbruchzeichenfolgen (\r\n oder nur \n) eine Rolle. Diese Feinheiten erschweren den Datenaustausch und machen ihn recht fehleranfällig. Ähnliche Probleme bergen auch binäre Formate, mit denen sich beispielsweise die Inspektion und Modifikation von Daten schwieriger gestalten. Diese Negativpunkte gelten eingeschränkt auch für die in Java integrierte Serialisierung. Wenn eine menschenlesbare Darstellung gewünscht ist, kann man CSV nutzen, das sich vor allem für Listen von Daten eignet, sich gut in Excel importieren und dort verarbeiten lässt. Eine Schwäche von CSV ist aber, dass damit hierarchische Strukturen nur umständlich abbildbar sind. Darüber hinaus lassen sich Metainformationen – wie z. B. die Informationen über die Bedeutung der einzelnen Daten – mithilfe von CSV nur mühsam transportieren. Als Abhilfe sieht man manchmal, dass die erste Zeile als eine Art Kommentar ausgelegt ist und dort die Spalten statt den Nutzinhalt die Bedeutung der Daten bzw. Attributnamen enthalten, etwa wie folgt:

Vorname,  Name,         Wohnort
Michael,  Inden,        Zürich
Clemens,  Gugenberger,  Aachen
Carsten,  Kern,         Düren
...

Zwar ist diese Art der Dokumentation für uns als Menschen hilfreich, jedoch kann dies die Verarbeitung mit Programmen erschweren, da hier wieder spezielle Prüfungen erfolgen müssen und Sonderfälle zu behandeln sind.

Nach diesem kurzen Ausflug zu CSV kommen wir wieder zu XML. Es ist sicherlich keine eierlegende Wollmilchsau, jedoch besitzt es gegenüber anderen Formaten unter anderem folgende positive Eigenschaften:

Neben diesen ganzen positiven Aspekten sollte man allerdings nicht verschweigen, dass XML-Dokumente durch die Vielzahl an Tags mitunter schwerfällig zu lesen sind und schnell recht umfangreich und unübersichtlich werden. Schlimmer noch: Durch die Wiederholung der Tag-Namen in Start- und End-Tag findet man eigentlich fast immer mehr Tags als Nutzinformationen. Als Folge wird es mitunter schwierig, relevante Informationen aus der »Textwüste« herauszulesen. Deswegen wird XML auch als »overly verbose« bezeichnet. Gerade wenn viele Datensätze im XML repräsentiert werden, steht die Größe des XML-Dokuments in keinem guten Verhältnis zu den tatsächlich zu transportierenden Nutzdaten. Als Alternative zu XML erfreut sich daher das deutlich kompaktere Datenformat JSON wachsender Beliebtheit. Darauf werde ich in Abschnitt 1.5 eingehen.

Abschließend möchte ich in noch erwähnen, dass XML die Grundlage für verschiedene spezifische Auszeichnungssprachen bildet, z. B. SVG (Scalable Vector Graphics) zur Beschreibung von Vektorgrafiken oder MathML zur Beschreibung mathematischer Formeln.

1.1.1 Bestandteile und Aufbau eines XML-Dokuments

Wie bereits angedeutet, hat jedes XML-Dokument einen definierten Aufbau und muss gewissen Regeln folgen, beispielsweise müssen Elemente korrekt verschachtelt sein. Schauen wir nun auf einige Vorgaben zum Aufbau eines XML-Dokuments.

Elemente, Tags und Attribute

Die Kombination aus öffnendem und schließendem Tag sowie alles, was dazwischen steht, wird als Element bezeichnet. Elemente beschreiben Daten und können weitere Subelemente, Attribute und auch textuelle Nutzdaten enthalten. Ein Element definiert eine semantische Einheit und dient zur Strukturierung der Daten.. Nachfolgend schauen wir nochmals auf das schon gezeigte Beispiel der Personen:

<Personen>
    <Person vorname="Michael" name="Inden" alter="44"></Person>
    <Person vorname="Hans" name="Meyer" alter="32"></Person>
    <Person vorname="Peter" name="Muster" alter="55" />
</Personen>

Die Eigenschaften von Elementen lassen sich entweder durch Subelemente oder in Form von Attributen definieren. In der XML-Gemeinde ist man sich nicht immer einig, wann man Subelemente nutzen sollte und wann Attribute zu bevorzugen sind. Grundsätzlich können allerdings nur solche Eigenschaften als Attribut modelliert werden, die sich sinnvoll als Text darstellen lassen – also Zahlen und Texte, jedoch keine komplexeren Informationen.

Attribute besitzen in XML einen Namen und einen Wert, wobei Attributwerte immer textueller Natur sind und daher in Anführungszeichen notiert werden. Das ist ein Unterschied zu HTML, das die Angabe von Zahlenliteralen erlaubt, etwa width=100.

Darüber hinaus ist im Gegensatz zu HTML die Groß-/Kleinschreibung für Tags in XML von Relevanz: Die Angaben <Person> und <person> werden beim Auswerten eines XML-Dokuments als unterschiedliche Elemente angesehen.

Die Namen für Elemente kann man relativ frei vergeben, jedoch darf der Name nicht mit xml oder Zahlen, Bindestrichen usw., sondern nur mit Buchstaben beginnen, ansonsten ist man in den nachfolgenden Zeichen recht frei. Allerdings sollte man bei der Namensgebung auf Verständlichkeit achten.

Bedeutung von Tags und Elementen

In XML dienen Elemente bekanntermaßen der Beschreibung der Daten. Sofern die Namen der Elemente und die ihrer Attribute sinnvoll gewählt sind, lässt sich eine verständliche, im Idealfall fast selbsterklärende Beschreibung und Repräsentation von Daten vornehmen.

Die im einführenden Beispiel genutzten Tags hätten auch anders benannt sein können, etwa Mitglieder und Mitglied für eine Vereinsverwaltung oder Kundenstamm und Kunde für eine Kundenverwaltung. Das Besondere an XML ist, dass man mit Tags Semantik beschreiben kann und dies dabei hilft, eine sprechende, verständliche und menschenlesbare Repräsentation der Nutzdaten aufzubereiten. Das ist ein großer Vorteil von XML gegenüber vielen anderen Notationsformen.

Prolog und Processing Instructions

Neben den eigentlichen Nutzdaten können in einem XML-Dokument auch Metainformationen in Form von sogenannten Processing Instructions hinterlegt werden. Diese werden im XML-Dokument durch <? ?> markiert. Derart gekennzeichnete Informationen werden bei der Auswertung (dem sogenannten Parsing) des XML-Dokuments speziell behandelt und können spezifische Verarbeitungsschritte auslösen.

Ganz elementar ist jedoch eine Prolog genannte Metainformation, die von ihrer Syntax stark an eine Processing Instruction erinnert. Jedes XML-Dokument sollte mit einem Prolog ähnlich zu Folgendem starten, um festzulegen, dass die nachfolgenden Daten ein XML-Dokument gemäß der Version 1.0 der XML-Spezifikation1 sind, in dem das angegebene Zeichensatz-Encoding, hier UTF-8, genutzt wird:

<?xml version="1.0" encoding="UTF-8" ?>

Zwar ist ein Prolog optional, wird er aber angegeben, so muss er am Beginn des XML-Dokuments stehen. Weil XML-Dokumente auch Sonderzeichen oder Umlaute enthalten können, die in unterschiedlichen Zeichensatz-Encodings unterschiedlich dargestellt werden, ist es sehr sinnvoll, das verwendete Zeichensatz-Encoding anzugeben und das XML-Dokument auch gemäß des angegebenen Encodings abzuspeichern.2 Falls nichts angegeben wurde, wird standardmäßig UTF-8 genutzt. Als Codierungen findet man auch ISO-8859-1 oder UTF-16.

Kommentare

Mitunter ist es zum Verständnis der Daten sinnvoll, diese mit Kommentaren zu versehen, die bei der Auswertung des Dokuments ignoriert werden. Im einführenden Beispiel haben wir Kommentare und deren Syntax <!-- Kommentar --> bereits kennengelernt – eine Verschachtelung ist jedoch nicht erlaubt.

Spezialzeichen

Bei der Beschreibung der Syntax von XML haben wir gesehen, dass diverse Zeichen eine Bedeutung tragen, etwa <, >, ", ' und &. Teilweise sollen diese Zeichen Bestandteil der Werte von Elementen und Attributen sein, etwa wenn in einer XML-Datei mathematische Ausdrücke abzubilden sind. Etwas naiv könnte man diese wie folgt notieren:

<Spezialzeichen>
    <Frage>Bitte antworte: Wie lautet das Ergebnis der Berechnung 44 / 11? &
                 wen interessiert das?</Frage>
    <Gleichung formel="a < b & b < c => a < c"/>
</Spezialzeichen>

Dadurch käme es beim Parsing zu Fehlern. Weil es mitunter nötig ist, diese Zeichen in XML repräsentieren zu können, gibt es die in Tabelle 1-1 gezeigten vordefinierten Ersatzzeichenfolgen.

Tabelle 1-1 Vordefinierte Ersetzungszeichenfolgen bei XML

Zeichen

Bedeutung

<

&lt;

>

&gt;

"

&quot;

'

&apos;

&

&amp;

Mit diesem Wissen machen wir uns an die Korrektur und schreiben Folgendes: