© Excellent backgrounds/Shutterstock.com
JAX-RS 2.0 und WebSocket

Entenhausen an der Börse


Die Java-EE-7-Plattform kann mit einigen zusätzlichen JAX-RS-Features dienen und stellt mit WebSocket eine neue, interessante Technologie bereit. Der folgende Artikel zeigt anhand eines praktischen Beispiels, bei dem ein Börsenkursdienst für die Bewohner von Entenhausen entwickelt werden soll, wie sie sich einsetzen lässt.

Im ersten Teil dieser vierteiligen Serie (im Java Magazin 10.2014) haben wir uns die wesentlichen Änderungen und Neuerungen der siebten Ausgabe der Java Enter­prise Edition im Überblick angesehen. Im aktuellen Artikel geht es um die praktische Nutzung dieser Technologien. Anhand eines konkreten Beispiels schauen wir uns folgend das Client-API und die Filter von JAX-RS 2.0 an. Weiterhin setzen wir WebSocket ein, um über am Server geänderte Daten im Client umgehend informiert zu werden.

Nachdem mein Patenkind David in den letzten Monaten zum großen Entenhausen-Fan mutiert ist, blieb mir nichts anderes übrig, als mich ebenfalls damit zu beschäftigen. Damit das umfassende Studium dieser fiktiven Welt inklusive seiner Charaktere nicht ganz umsonst war, wollen wir folgendes Szenario für unser Beispiel wählen: Stellen Sie sich vor, die Bewohner von Entenhausen rufen eine Börse ins Leben, um ihren Bewohnern einen Marktplatz für den Wertpapierhandel zu bieten. Jeder Entenhausener kann mit seinem Unternehmen an der Börse notieren. Dagobert Duck Enterprises (DAGO), die Panzerknacker AG (PANZ) und die Daniel Düsentrieb Inc. (DANI) nutzen diese Möglichkeit sofort – jeder allerdings mit einem anderen Hintergedanken: Die reichste Ente der Welt hofft durch den Börsengang noch viel reicher zu werden, die Panzerknacker wollen die Börsengeschäfte zum Geldwaschen nutzen und Entenhausens größter Erfinder möchte so seine Forschungsprojekte finanzieren. Es gilt nun im ersten Schritt, einen Dienst zu implementieren, über den sich der aktuelle Börsenkurs eines jeden Unternehmens abfragen lässt. Auch das Setzen eines Kurses muss möglich sein. Später soll man sich in Echtzeit über Kursänderungen informieren lassen können.

Da der Börsenkursdienst auch direkt aus Applikationen, die ausschließlich im Browser laufen, nutzbar sein soll, werden wir einen RESTful Web Service implementieren. Sobald diese Lösung steht, ergänzen wir sie um einen WebSocket-Endpunkt, um Kursänderungen live nachverfolgen zu können.

RESTlos glücklich dank neuer Features

Da wir auf der grünen Wiese beginnen, können wir technologisch aus dem Vollen schöpfen. So setzen wir den WildFly 8.1.0 in der finalen Version als Applikationsserver ein und werden die neuen Java-8-Features nutzen. Ausrollen werden wir unsere Dienste in Form einer klassischen Java-Enterprise-Webapplikation. Die Clientprogramme setzen wir in Form eines eigenen Java-Projekts um.

Zum Speichern der Börsenkurse nutzen wir die als Singleton ausgeführte Session Bean MarketPriceStore (Listing 1). Im Grunde bauen wir damit einen klassischen Key-Value Store nach. Als Schlüssel wird die Unternehmenskennung verwendet, als Wert der aktuelle Börsenkurs. Die Daten werden nicht persistent gehalten. Dieses Feature folgt erst in einem späteren Sprint. Der Store bietet dem Entwickler mit store() und retrieve() die klassischen Methoden zum Speichern und Abfragen von Daten. Zwei Besonderheiten sind zu beachten: Ändert sich durch das Speichern der Börsenkurs eines Unternehmens, so wird ein CDI-Event abgefeuert. Alle, die solche Ereignisse überwachen, bekommen die Unternehmenskennung und den neuen Kurswert in Form eines ChangeEvent-Objekts übermittelt. Außerdem liefert die Methode retrieve() nicht null zurück, wenn kein Börsenkurswert gefunden wird, sondern verwendet Optional<Double> als Rückgabetyp. Diese mit Java 8 neu eingeführte Klasse stellt eine Art Wrapper um ein Objekt dar und bietet verschiedene Methoden, dank der sich komfortabel mit Objekten arbeiten lässt, die möglicherweise leer sind.

Listing 1

... @Singleton @LocalBean public class MarketPriceStore { private Map<String, Double> map = new HashMap<String, Double>(); @Inject Event<ChangeEvent> eventSource; public void store(String companyId, Double marketPriceNew) { Double marketPriceOld = map.get(companyId); if (!Objects.equals(marketPriceOld, marketPriceNew)) { map.put(companyId, marketPriceNew); eventSource.fire(new ChangeEvent(companyId, marketPriceNew)); } } public Optional<Double> retrieve(String key) { return Optional.ofNullable(map.get(key)); } }

Zur Erstellung des RESTful Web Service SimpleStockMarketResource (Listing 2) nutzen wir mit JAX-WS klarerweise die zugehörige Standardtechnologie der Enterprise-Plattform. Den Store zur Datenhaltung lassen wir uns injizieren. Als HTTP-Methoden unterstützen wir PUT und GET, wobei sich mit PUT nicht nur Börsenwerte aktualisieren, sondern auch anlegen lassen. In der Methode retrieve() delegieren wir die eigentliche Abfrage an unseren selbstimplementierten Key-Value Store. Da dieser einen optionalen Rückgabetyp hat, können wir ohne explizite null-Überprüfung und mithilfe eines Lambdas recht elegant den Statuscode setzen. Damit der Web Service tatsächlich ausgerollt wird, müssen wir in web.xml noch ein Servlet mit dem Namen javax.ws.rs.core.Application eintragen. Unter jboss-web.xml tragen wir als Kontextwurzel entenhausen ein. Danach kann es mit dem Deployment auch schon losgehen. Unser RESTful Web Service wird sogleich auf dem lokalen Rechner mit WildFly-...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang