Java - von am Sunday, January 27, 2008 23:45 - 8 Kommentare

WebService in Java

Mit Erscheinen des JDK 6 ist die Implementation von WebServices noch einfacher geworden, da die benötigten Libraries aus dem Java Web Services Developer Pack (JWSDP) Einzug in das JDK 6 Release gefunden haben. Alternativ lässt sich beispielsweise immer noch Apache Axis verwenden, aber für das folgende, einfache, Beispiel nutzen wir die Standardlibraries. Implementiert werden soll eine einfache Anwendung, die die Summe zweier übergebenen Werte zurückgibt und diese Funktionalität als WebService bereitstellt.

Vorweg sei Ihnen zum besseren Verständnis der Thematik das absolut lesenswerte Standardwerk von Ingo Melzer, Service-orientierte Architekturen mit Web Services: Konzepte – Standards – Praxis, ans Herz gelegt. Es geht nicht nur auf WebServices und die damit zusammenhängenden Technologien, sondern auch auf die Service-orientierten Architekturen ein und sollte in keinem IT-Bücherschrank fehlen.

Was ist ein WebService?

Vereinfacht ausgedrückt stellt ein Anbieter über einen WebService einen Dienst bereit, der von externen Anwendungen angesprochen werden kann. Über den Verzeichnisdienst UDDI oder auch ebXML können solche Dienste öffentlich gemacht werden und über die Web Services Description Language (WSDL), einer XML-Spezifikation, wird angebundenen Anwendungen bekannt gegeben, welche Funktionen der Dienst genau bereitstellt. Die Kommunikation findet über das Simple Object Access Protocol (SOAP), einem XML-basierten Protokoll, statt.
Der Vorteil dieser Gesamtkombination ist, daß die Dienste, als auch die sie benutzenden Anwendungen, in grundverschiedenen Programmiersprachen und Plattformen implementiert sein können. Ein Dienst kann beispielsweise in .NET implementiert sein, seine Schnittstellen als WebService per UDDI und WSDL öffentlich machen und über SOAP mit einem PHP oder Java-Client kommunizieren und Aufrufe seiner Funktionen ermöglichen.

Implementation der WebService Klasse

Prinzipiell lässt sich jede Klasse als WebService exportieren. Alles was wir dafür tun müssen ist, die in Java 5 eingeführten Java Annotations dazu zu verwenden, unsere Klassen als WebService zu deklarieren. Die folgende normale Java-Klasse:

  1. package de.theserverside.webservice.service;
  2.  
  3. public class Calculator {
  4.   public long addValues(int val1, int val2) {
  5.     return val1 + val2;
  6.   }
  7. }

… wird, versehen mit WebService-spezifischen Java Annotations, zu folgender Klasse:

  1. package de.theserverside.webservice.service;
  2.  
  3. import javax.jws.WebService;
  4. import javax.jws.soap.SOAPBinding;
  5. import javax.jws.soap.SOAPBinding.Style;
  6.  
  7. @WebService
  8. @SOAPBinding(style=Style.RPC)
  9.  
  10. public class Calculator {
  11.   public long addValues(int val1, int val2) {
  12.     return val1 + val2;
  13.   }
  14. }

Über die Angabe @SOAPBinding(style=Style.RPC) geben wir an, daß diese Klasse per SOAP-Protokoll gebunden werden soll und die Kommunikation prozedurorientiert (RPC = Remote Procedure Call) stattfindet. Das zeigt an, daß Aufrufe Parameter enthalten und Werte zurückgegeben werden. Die Angabe Style.DOCUMENT hieße, daß Aufrufe Dokumente enthielten.

Implementation des WebService Servers

Diese Klasse möchten wir jetzt als WebService veröffentlichen und implementieren dazu einen Server, der sie nach außen veröffentlicht. Die Publizierung findet dabei über den integrierten HTTP-Server statt:

  1. package de.theserverside.webservice.server;
  2.  
  3. import javax.xml.ws.Endpoint;
  4. import de.theserverside.webservice.service.Calculator;
  5.  
  6. public class CalculatorServer {
  7.   public static void main (String args[]) {
  8.     Calculator server = new Calculator();
  9.     Endpoint endpoint =
  10.       Endpoint.publish("http://localhost:8080/calculator", server);
  11.   }
  12. }

Starten Sie diese Klasse aus der Entwicklungsumgebung heraus und prüfen Sie den Erfolg der Operation, indem Sie im Webbrowser die folgende URL aufrufen:

  1. http://localhost:8080/calculator?wsdl

Sie sollten etwa folgende Ausgabe erhalten:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
  3. <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
  4. <definitions
  5.  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  6.  xmlns:tns="http://service.webservice.theserverside.de/"
  7.  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  8.  xmlns="http://schemas.xmlsoap.org/wsdl/"
  9.  targetNamespace="http://service.webservice.theserverside.de/"
  10.  name="CalculatorService">
  11. <types></types>
  12. <message name="addValues">
  13.   <part name="arg0" type="xsd:int"></part>
  14.   <part name="arg1" type="xsd:int"></part>
  15. </message>
  16. <message name="addValuesResponse">
  17.   <part name="return" type="xsd:long"></part>
  18. </message>
  19. <portType name="Calculator">
  20.   <operation name="addValues" parameterOrder="arg0 arg1">
  21.     <input message="tns:addValues"></input>
  22.     <output message="tns:addValuesResponse"></output>
  23.   </operation>
  24. </portType>
  25. [...]

Implementation des WebService Clients

Bisher haben Sie die wichtigsten Informationen bekommen, um einen WebService-Dienst zu entwickeln. Für den programmatischen Zugriff auf diesen Dienst möchten wir jetzt aus der publizierten WSDL-Datei die benötigten Service-Klassen generieren, die wir für unseren Client benötigen. Rufen Sie dazu, im Source-Verzeichnis eines zweiten Java-Projekts, auf der Shell den folgenden Befehl auf:

  1. wsimport -keep http://localhost:8080/calculator?wsdl

Über den -keep-Parameter werden die generierten Java-Klasse behalten und nicht nach dem Kompilieren gelöscht. Wenn der Befehl fehlerlos durchgelaufen ist finden Sie folgende vier generierten, bzw. kompilierten, Dateien vor:

  1. Calculator.java
  2. Calculator.class
  3. CalculatorService.java
  4. CalculatorService.class

Jetzt, da wir das Interface und die dazugehörige Service-Klasse generiert haben, können wir uns an die Implementation des Clients machen. Auch diese gestaltet sich recht einfach, wie das folgende Codestück zeigt:

  1. package de.theserverside.webservice.client;
  2.  
  3. import de.theserverside.webservice.service.Calculator;
  4. import de.theserverside.webservice.service.CalculatorService;
  5.  
  6. public class CalculatorClient {
  7.     public static void main(String args[]) {
  8.         CalculatorService service = new CalculatorService();
  9.         Calculator calculator = service.getCalculatorPort();
  10.         System.out.println("Summe: " + calculator.addValues(17, 13));
  11.     }
  12. }

Der aus der WSDL generierte CalculatorService übernimmt die Kommunikation zum Server. Ein Handle auf unseren Calculator erhalten wir über den Aufruf von getCalculatorPort(), welches wir anschließend für Zugriffe auf unsere Klasse nutzen.

Starten Sie diese Klasse und Sie erhalten die folgende Ausgabe:

  1. Summe: 30

Sourcecode zum Artikel

Die beiden Java-Projekte, den Client und den Server, können Sie hier herunterladen:
WebService in Java – Client
WebServices in Java – Server

Weiterführende Literatur

Weitere Informationen zur Implementation von WebServices in Java, hier mit dem Framework AXIS2, finden Sie in dem Buch Java Web Services mit Apache Axis2 von Thilo Frotscher, Marc Teufel und Dapeng Wang, die auch für diverse Artikel im Java Magazin verantwortlich zeichnen. Im Zusammenhang mit Service-orientierten Architekturen (SOA) werden WebServices im von Lesern sehr gut bewerteten Service-orientierte Architekturen mit Web Services: Konzepte – Standards – Praxis beschrieben.

Be Sociable, Share!


Kommentare

Kommentieren

Weitere Empfehlungen: