4. Der Webdienst J2EE für Termine
Kommen wir zurück zur Architektur der zu entwickelnden Anwendung:
![]() |
In diesem Abschnitt befassen wir uns mit der Erstellung des Webdienstes J2EE [1], der auf einem Sun-/Glassfish-Server ausgeführt wird.
4.1. Die Datenbank
Die Datenbank, die wir [dbrdvmedecins] nennen werden, ist eine MySQL5-Datenbank mit vier Tabellen:

4.1.1. Die Tabelle [MEDECINS]
Sie enthält Informationen zu den Ärzten, die von der Anwendung [RdvMedecins] verwaltet werden.
![]() | ![]() |
- ID: Identifikationsnummer des Arztes – Primärschlüssel der Tabelle
- VERSION: Nummer zur Identifizierung der Zeilenversion in der Tabelle. Diese Nummer wird bei jeder Änderung an der Zeile um 1 erhöht.
- NOM: Name des Arztes
- PRENOM: sein Vorname
- TITRE: sein Titel (Fräulein, Frau, Herr)
4.1.2. Die Tabelle [CLIENTS]
Die Patienten der verschiedenen Ärzte sind in der Tabelle [CLIENTS] gespeichert:
![]() | ![]() |
- ID: Nummer zur Identifizierung des Kunden – Primärschlüssel der Tabelle
- VERSION: Nummer zur Identifizierung der Version der Zeile in der Tabelle. Diese Nummer wird bei jeder Änderung an der Zeile um 1 erhöht.
- NOM: Name des Kunden
- PRENOM: sein Vorname
- TITRE: seine Anrede (Fräulein, Frau, Herr)
4.1.3. Die Tabelle [CRENEAUX]
Sie listet die Zeitfenster auf, in denen RV möglich sind:
![]() |
![]() |
- ID: Nummer zur Identifizierung des Zeitfensters – Primärschlüssel der Tabelle (Zeile 8)
- VERSION: Nummer zur Identifizierung der Version der Zeile in der Tabelle. Diese Nummer wird bei jeder Änderung an der Zeile um 1 erhöht.
- ID_MEDECIN: Nummer zur Identifizierung des Arztes, zu dem dieses Zeitfenster gehört – Fremdschlüssel auf die Spalte MEDECINS (ID).
- HDEBUT: Startzeit des Zeitfensters
- MDEBUT: Startminute des Zeitfensters
- HFIN: Endzeit des Zeitfensters
- MFIN: Minuten des Zeitfensterschlusses
Die zweite Zeile der Tabelle [CRENEAUX] (siehe [1] oben) gibt beispielsweise an, dass der Termin Nr. 2 um 8:20 Uhr beginnt und um 8:40 Uhr endet und der Ärztin Nr. 1 (Frau Marie PELISSIER).
4.1.4. Die Tabelle [RV]
Sie listet die für jeden Arzt vergebenen RV auf:
![]() |
- ID: Nummer, die den RV eindeutig identifiziert – Primärschlüssel
- JOUR: Tag des RV
- ID_CRENEAU: Zeitfenster des RV – Fremdschlüssel auf das Feld [ID] der Tabelle [CRENEAUX] – legt sowohl das Zeitfenster als auch den betreffenden Arzt fest.
- ID_CLIENT: Kundennummer, für die die Reservierung vorgenommen wird – Fremdschlüssel auf das Feld [ID] der Tabelle [CLIENTS]
Diese Tabelle verfügt über eine Eindeutigkeits für die Werte der verknüpften Spalten (JOUR, ID_CRENEAU):
Wenn eine Zeile der Tabelle [RV] den Wert (JOUR1, ID_CRENEAU1) für die Spalten (JOUR, ID_CRENEAU) aufweist, darf dieser Wert an keiner anderen Stelle vorkommen. Andernfalls würde dies bedeuten, dass zwei RV gleichzeitig für denselben Arzt erfasst wurden. Aus Sicht der Java-Programmierung löst der Treiber JDBC der Datenbank in diesem Fall einen SQLException aus.
Die Zeile mit dem Wert 3 für id (siehe [1] oben) bedeutet, dass am 23.08.2006 ein RV für den Terminblock Nr. 20 und den Kunden Nr. 4 gebucht wurde. Aus der Tabelle [CRENEAUX] geht hervor, dass der Termin Nr. 20 dem Zeitfenster 16:20 – 16:40 Uhr entspricht und der Ärztin Nr. 1 (Frau Marie PELISSIER) zugeordnet ist. Aus der Tabelle [CLIENTS] geht hervor, dass es sich bei Kunde Nr. 4 um Frau Brigitte BISTROU handelt.
4.2. Erstellung der Datenbank
Erstellen Sie die Datenbank MySql [dbrdvmedecins] mit einem Tool Ihrer Wahl. Zum Anlegen der Tabellen und zum Befüllen dieser können Sie das Skript [createbd.sql] verwenden, das Ihnen zur Verfügung gestellt wird. Sein Inhalt lautet wie folgt:
4.3. Die Elemente der serverseitigen Architektur
Kommen wir zurück zur Architektur der zu entwickelnden Anwendung:
![]() |
Auf der serverseitigen Seite wird die Anwendung bestehen aus:
- aus einer JPA-Schicht, die die Arbeit mit der BD mithilfe von Objekten ermöglicht
- eines EJB, das für die Verwaltung der Vorgänge mit der JPA-Schicht zuständig ist
- einem Webservice, der dafür zuständig ist, die Schnittstelle des EJBs in Form eines Webservices für entfernte Clients bereitzustellen.
Die Elemente (b) und (c) implementieren die im vorherigen Schema dargestellte [dao]-Schicht. Es ist bekannt, dass eine Anwendung über die Protokolle RMI und JNDI auf ein entferntes EJB zugreifen kann. In der Praxis beschränkt dies die Clients auf Java-Clients. Ein Webdienst nutzt ein standardisiertes Kommunikationsprotokoll, das von verschiedenen Sprachen implementiert wird: .NET, PHP, C++, ... Genau das wollen wir hier anhand eines .NET-Clients veranschaulichen.
Eine kurze Einführung in Webdienste findet sich im Kurs [ref1], Absatz 14, Seite 109.
Ein Webdienst kann auf zwei Arten implementiert werden:
- durch eine mit @WebService annotierte Klasse, die in einem Web-Container ausgeführt wird
![]() |
- durch ein mit @WebService annotiertes EJB, das in einem EJB-Container ausgeführt wird
![]() |
![]() |
Wir werden hier die erste Lösung verwenden:
Im Kurs [ref1], Absatz 14, Seite 109, findet sich ein Beispiel für die zweite Lösung.
4.4. - und Hibernate-Konfiguration des GlassFish-Servers
Je nach Version verfügt der mit NetBeans gelieferte GlassFish-Server V2 möglicherweise nicht über die Hibernate-Bibliotheken, die die JPA-/Hibernate-Schicht benötigt. Sollten Sie im weiteren Verlauf des Tutorials feststellen, dass Glassfish keine JPA-/Hibernate-Implementierung anbietet oder dass beim Deployen der Dienste eine Ausnahme auftritt, die darauf hinweist, dass die Hibernate-Bibliotheken nicht gefunden werden, müssen Sie die Bibliotheken im Ordner [<glassfish>/domains/domain1/lib/ext] hinzufügen und anschließend den Glassfish-Server neu starten:
![]() |
|
Die Hibernate-Bibliotheken befinden sich in der ZIP-Datei, die dem Tutorial beiliegt.
4.5. Die Tools zur automatischen Generierung von NetBeans
Kommen wir zurück zu der Architektur, die wir aufbauen müssen:
![]() |
Mit NetBeans ist es möglich, die Schicht [JPA] und die Schicht [Ejb] automatisch zu generieren, die den Zugriff auf die generierten Entitäten JPA steuern. Es ist interessant, diese Methoden der automatischen Generierung zu kennen, da der generierte Code wertvolle Hinweise darauf gibt, wie JPA-Entitäten oder der EJB-Code, der diese verwendet, geschrieben werden sollten.
Im Folgenden beschreiben wir einige dieser Werkzeuge zur automatischen Generierung. Um den generierten Code zu verstehen, sind fundierte Kenntnisse über die Entitäten JPA, [ref1] sowie EJB und [ref2] erforderlich.
Einrichten einer NetBeans-Verbindung zur Datenbank
- Starten Sie die Entitäten SGBD und MySQL 5, damit die Entität BD verfügbar ist
- Erstellen Sie eine NetBeans-Verbindung zur Datenbank [dbrdvmedecins]
![]() |
- auf der Registerkarte [Files] im Zweig [Databases] [1] den JDBC-Treiber MySQL [2] auswählen
- und wählen Sie anschließend die Option [3] „Connect Using“ aus, um eine Verbindung zu einer Datenbank MySQL
- in [4], geben Sie die angeforderten Informationen ein
- und bestätigen Sie anschließend in [5]
![]() |
- in [6]: Die Verbindung wurde hergestellt. Dort sind die vier Tabellen der verbundenen Datenbank zu sehen.
Erstellung eines EJB-Projekts
![]() |
- in [1], eine neue Anwendung erstellen, ein EJB-Modul
- in [2], die Kategorie [Java EE] auswählen und in [3] den Typ [EJB Module]
![]() |
- in [4] einen Ordner für das Projekt auswählen und in [5] einen Namen vergeben – anschließend den Assistenten abschließen
- in [6] das generierte Projekt
Hinzufügen einer Ressource JDBC zum Glassfish-Server
Wir werden eine Ressource JDBC zum Glassfish-Server hinzufügen.
![]() |
![]() |
- Starten Sie auf der Registerkarte „[Services]“ den GlassFish-Server „[2, 3]“
- Klicken Sie auf der Registerkarte „[Projects]“ mit der rechten Maustaste auf das EJB-Projekt und wählen Sie unter „[5]“ die Option „[New / Other]“ aus, um dem Projekt ein Element hinzuzufügen.

- in [6], wählen Sie die Kategorie „[Glassfish]“ aus und geben Sie in „[7]“ an, dass Sie eine Ressource „JDBC“ erstellen möchten, indem Sie den Typ „[JDBC Resource]“ auswählen
- in [8] angeben, dass diese Ressource JDBC ihren eigenen Verbindungspool verwenden soll
- in [9] angeben, dass diese Ressource JDBC einen eigenen Verbindungspool verwenden wird
- in [10]: Fahren Sie mit dem nächsten Schritt fort
![]() |
- in [11] werden die Eigenschaften des Verbindungspools der Ressource JDBC definiert
- in [12], den Verbindungspool benennen
- in [13] die zuvor erstellte NetBeans-Verbindung [dbrdvmedecins] auswählen
- in [14], zum nächsten Schritt übergehen
- in [15]: Auf dieser Seite muss normalerweise nichts geändert werden. Die Eigenschaften der Verbindung zur Datenbank MySQL [dbrdvmedecins] wurden aus denen der zuvor erstellten NetBeans-Verbindung [dbrdvmedecins] übernommen
- in [16], fahren Sie mit dem nächsten Schritt fort
![]() |
- in [17], behalten Sie die vorgeschlagenen Standardwerte bei
- in [18], den Assistenten abschließen. Dieser erstellt die Datei [sun-resources.xml] [19] mit folgendem Inhalt:
Die oben genannte Datei enthält alle im Assistenten eingegebenen Informationen im Format XML. Sie wird von NetBeans verwendet, um den GlassFish-Server aufzufordern, die in Zeile 4 definierte Ressource „jdbc/dbrdvmedecins“ anzulegen.
Erstellung einer Persistenz-Einheit
Die Persistenz-Einheit [persistence.xml] konfiguriert die Schicht JPA: Sie gibt die verwendete Implementierung JPA (Toplink, Hibernate, …) an und konfiguriert diese.
![]() |
![]() |
- In [1] mit der rechten Maustaste auf das EJB-Projekt klicken und [New / Other] auswählen In [2]
- in [3], wählen Sie die Kategorie [Persistence] aus und geben Sie dann in [4] an, dass Sie eine Persistenz-Einheit JPA erstellen möchten
![]() |
- in [5], geben Sie der erstellten Persistenz-Einheit einen Namen
- in [6], wählen Sie [Hibernate] als Implementierung für JPA
- in [7] die soeben erstellte GlassFish-Ressource „jdbc/dbrdvmedecins“ auswählen
- in [8] angeben, dass bei der Instanziierung der Schicht JPA keine Aktion an der Datenbank durchgeführt werden soll
- den Assistenten abschließen
- In [9] die vom Assistenten erstellte Datei [persistence.xml]
Ihr Inhalt lautet wie folgt:
Auch hier werden die im Assistenten eingegebenen Informationen im Format XML übernommen. Diese Datei reicht nicht aus, um mit der Datenbank MySQL5 „dbrdvmedecins“ zu arbeiten. Wir müssten Hibernate den zu verwaltenden Typ SGBD mitteilen. Dies wird zu einem späteren Zeitpunkt erfolgen.
Erstellung der Entitäten JPA
![]() |
![]() |
![]() |
- In [1] mit der rechten Maustaste auf das Projekt klicken und in [2] die Option [New / Other]
- in [3] die Kategorie [Persistence] auswählen und anschließend in [4] angeben, dass Sie Entitäten JPA aus einer bestehenden Datenbank erstellen möchten.
![]() |
- In [5] wählen Sie die Quelle JDBC „jdbc/dbrdvmedecins“ aus, die wir erstellt haben
- in [6], die vier Tabellen der zugehörigen Datenbank
- in [7,8] alle in die Generierung der Entitäten einbeziehen JPA
- in [9], den Assistenten fortsetzen
![]() |
- in [10]: Die Entitäten JPA, die generiert werden sollen
- in [11], geben Sie dem Paket der Entitäten JPA
- in [12], den Java-Typ auswählen, der die von der Schicht JPA zurückgegebenen Objektlisten kapseln soll
- den Assistenten abschließen
- in [13], die vier generierten Entitäten JPA, jeweils eine für jede Tabelle der Datenbank.
Hier ist beispielsweise der Code der Entität [Rv], die eine Zeile der Tabelle [rv] aus der Datenbank [dbrdvmedecins] darstellt.
Erstellung der EJB-Zugriffsebene für die Entitäten JPA
![]() |
![]() |
- in [1] mit der rechten Maustaste auf das Projekt klicken und in [2] die Option [New / Other]
- in [3] die Kategorie [Persistence] und anschließend in [4] den Typ [Session Beans for Entity Classes] auswählen
![]() |
- in [5] werden die zuvor erstellten Entitäten JPA
- in [6], alle auswählen
- in [7] wurden sie ausgewählt
- in [8]: Fahren Sie mit dem Assistenten fort
![]() |
- in [9], geben Sie dem Paket der zu generierenden EJBs einen Namen
- in [10], angeben, dass die EJBs sowohl eine lokale als auch eine entfernte Schnittstelle implementieren müssen
- den Assistenten beenden
- in [11], die generierten EJBs
Hier ist beispielsweise der Code des EJB, der den Zugriff auf die Entität [Rv] verwaltet, also auf die Tabelle [rv] der Datenbank [dbrdvmedecins]:
Wie bereits erwähnt, kann die automatische Codegenerierung sehr hilfreich sein, um ein Projekt zu starten und sich mit den Entitäten JPA und EJB vertraut zu machen. Im weiteren Verlauf schreiben wir die Schichten JPA und EJB mit unserem eigenen Code neu, doch der Leser wird darin Informationen wiederfinden, die wir gerade bei der automatischen Generierung der Schichten behandelt haben.
4.6. Das NetBeans-Projekt des EJB-Moduls
Wir erstellen ein neues, leeres EJB-Modul (siehe Abschnitt 4.5):
![]() |
- Das Paket [rdvmedecins.entites] enthält die Entitäten der JPA-Schicht
- Das Paket [rdvmedecins.dao] implementiert das EJB der Schicht [dao]
- Das Paket [rdvmedecins.exceptions] implementiert eine anwendungsspezifische Ausnahmeklasse
Im Folgenden gehen wir davon aus, dass der Leser alle Schritte aus Abschnitt 4.5 befolgt hat. Einige davon muss er wiederholen.
4.6.1. Konfiguration der Schicht JPA
Zur Erinnerung: Die Architektur unserer Client-Server-Anwendung sieht wie folgt aus:
![]() |
Das NetBeans-Projekt:
![]() |
Die Schicht [JPA] wird durch die oben genannten Dateien [persistence.xml] und [sun-resources.xml] konfiguriert. Diese beiden Dateien werden von bereits bekannten Assistenten generiert:
- Die Erstellung der Datei [sun-resources.xml] wurde in Abschnitt 4.5 beschrieben.
- Die Erstellung der Datei [persistence.xml] wurde in Abschnitt 4.5 beschrieben.
Die generierte Datei „[persistence.xml]“ muss wie folgt geändert werden:
- Zeile 3: Der Transaktionstyp ist JTA: Die Transaktionen werden vom EJB3-Container von GlassFish verwaltet
- Zeile 4: Es wird eine JPA-/Hibernate-Implementierung verwendet. Zu diesem Zweck wurde die Hibernate-Bibliothek zum GlassFish-Server hinzugefügt (siehe Abschnitt 4.4).
- Zeile 5: Die von der JPA-Schicht verwendete Datenquelle JTA trägt den Namen JNDI „jdbc/dbrdvmedecins“.
- Zeile 8: Diese Zeile wird nicht automatisch generiert. Sie muss manuell hinzugefügt werden. Sie teilt Hibernate mit, dass das verwendete SGBD das MySQL5 ist.
Die Datenquelle „jdbc/dbrdvmedecins“ ist in der folgenden Datei [sun-resources.xml] konfiguriert:
- Zeilen 8–10: Die JDBC-Eigenschaften der Datenquelle (Datenbank-URL, Benutzername und Passwort). Die Datenbank MySQL dbrdvmedecins ist die in Abschnitt 4.1 beschriebene.
- Zeile 7: Die Eigenschaften des mit dieser Datenquelle verknüpften Verbindungspools
4.6.2. Die Entitäten der Schicht JPA
Zur Erinnerung: Die Architektur unserer Client-Server-Anwendung:
![]() |
Das NetBeans-Projekt:
![]() |
Das Paket [rdvmedecins.entites] implementiert die Schicht [Jpa].
In Abschnitt 4.5 haben wir gesehen, wie man die JPA-Entitäten einer Anwendung automatisch generieren kann. Wir werden diese Technik hier nicht verwenden, sondern die Entitäten selbst definieren. Diese werden jedoch einen Großteil des in Abschnitt 4.5 generierten Codes übernehmen. Hier möchten wir, dass die Entitäten [Medecin] und [Client] Unterklassen der Klasse [Personne] sind.
Die Klasse „Person“ wird verwendet, um Ärzte und Kunden darzustellen:
- Zeile 3: Es ist zu beachten, dass die Klasse [Personne] selbst keine Entität (@Entity) ist. Sie wird die übergeordnete Klasse für Entitäten sein. Die Annotation @MappedSuperClass kennzeichnet diese Situation.
Die Entität [Client] kapselt die Zeilen der Tabelle [clients]. Sie leitet sich von der vorherigen Klasse [Personne] ab:
- Zeile 3: Die Klasse [Client] ist eine JPA-Entität
- Zeile 4: Sie ist der Tabelle [clients] zugeordnet
- Zeile 5: Sie leitet sich von der Klasse [Personne] ab
Die Entität [Medecin], die die Zeilen der Tabelle [medecins] kapselt, folgt demselben Muster:
Die Entität [Creneau] kapselt die Zeilen der Tabelle [creneaux]:
- Die Zeilen 15–17 modellieren die „Eins-zu-Viele“-Beziehung, die zwischen der Tabelle [creneaux] und der Tabelle [medecins] der Datenbank besteht.
Die Entität [Rv] kapselt die Zeilen der Tabelle [rv]:
- Die Zeilen 15–17 modellieren die „Eins-zu-Viele“-Beziehung, die zwischen der Tabelle [rv] und der Tabelle [clients] der Datenbank besteht, und die Zeilen 18–20 die „Eins-zu-Viele“-Beziehung zwischen der Tabelle [rv] und der Tabelle [creneaux]
4.6.3. Die Ausnahmeklasse
![]() |
Die Ausnahmeklasse [RdvMedecinsException] der Anwendung lautet wie folgt:
- Zeile 6: Die Klasse leitet sich von der Klasse [RuntimeException] ab. Der Compiler erzwingt daher nicht, sie mit try/catch zu behandeln.
- Zeile 5: Die Annotation @ApplicationException sorgt dafür, dass die Ausnahme nicht von einer Ausnahme vom Typ [EjbException] „abgefangen“ wird.
Um die Annotation @ApplicationException zu verstehen, kehren wir zur serverseitigen Architektur zurück:
![]() |
Die Ausnahme vom Typ [RdvMedecinsException] wird von den Methoden des EJB der Schicht [dao] innerhalb des EJB3-Containers ausgelöst und von diesem abgefangen. Ohne die Annotation @ApplicationException kapselt der EJB3-Container die aufgetretene Ausnahme in eine Ausnahme vom Typ [EjbException] und löst diese erneut aus. Möglicherweise möchte man diese Kapselung nicht und eine Ausnahme vom Typ [RdvMedecinsException] aus dem Container Ejb3 herausgeben lassen. Dies ermöglicht die Annotation @ApplicationException. Darüber hinaus weist das Attribut (rollback=true) dieser Annotation den EJB3-Container an, dass die Transaktion mit dem SGBD rückgängig gemacht werden muss, falls die Ausnahme vom Typ [RdvMedecinsException] innerhalb einer Methode auftritt, die im Rahmen einer Transaktion mit einem SGBD ausgeführt wird. Technisch gesehen wird dies als „rollback“ der Transaktion bezeichnet.
4.6.4. Das EJB der Schicht [dao]
![]() |
![]() |
Die Java-Schnittstelle [IDao] der Schicht [dao] lautet wie folgt:
Die lokale Schnittstelle [IDaoLocal] des EJB leitet lediglich die vorherige Schnittstelle [IDao] ab:
Das Gleiche gilt für die Remote-Schnittstelle [IDaoRemote]:
Das EJB [DaoJpa] implementiert beide Schnittstellen, die lokale und die Remote-Schnittstelle:
- Zeile 3 gibt an, dass der Remote-EJB den Namen „rdvmedecins.dao“ trägt
- Zeile 4 gibt an, dass alle Methoden des EJB innerhalb einer vom EJB3-Container verwalteten Transaktion ausgeführt werden.
- Zeile 5 zeigt, dass das EJB die lokalen und entfernten Schnittstellen implementiert.
Der vollständige Code des EJB lautet wie folgt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
- Zeile 8: Das Objekt „EntityManager“, das den Zugriff auf den Persistenzkontext verwaltet. Bei der Instanziierung der Klasse wird dieses Feld vom EJB-Container mithilfe der Annotation „@PersistenceContext“ in Zeile 7 initialisiert.
- Zeile 15: Abfrage JPQL, die alle Zeilen der Tabelle [clients] in Form einer Liste von Objekten [Client] zurückgibt.
- Zeile 22: Entsprechende Abfrage für Ärzte
- Zeile 32: Eine Abfrage JPQL, die eine Verknüpfung zwischen den Tabellen [creneaux] und [medecins] durchführt. Sie wird über die ID des Arztes parametrisiert.
- Zeile 43: Eine Abfrage JPQL, die eine Verknüpfung zwischen den Tabellen [rv], [creneaux] und [medecins] herstellt und zwei Parameter hat: die ID des Arztes und den Tag des Termins.
- Zeilen 55–57: Erstellung eines Termins und anschließende Speicherung in der Datenbank.
- Zeile 67: Löschen eines Termins aus der Datenbank.
- Zeile 76: Führt eine SELECT-Abfrage in der Datenbank durch, um einen bestimmten Kunden zu finden
- Zeile 85: Gleiches für einen Arzt
- Zeile 94: Gleiches für einen Termin
- Zeile 103: dasselbe für einen Terminblock
- Alle Operationen mit dem Persistenzkontext „em“ aus Zeile 9 können zu Problemen mit der Datenbank führen. Daher sind sie alle von einem „try/catch“-Block umgeben. Die mögliche Ausnahme wird in der „hausinternen“ Ausnahme RdvMedecinsException gekapselt.
Das EJB-Modul erzeugt nach der Kompilierung eine .jar-Datei mit dem Namen „ “:
![]() |
4.7. Bereitstellung des EJB der Schicht [dao] mit NetBeans
Mit NetBeans lässt sich das zuvor erstellte EJB auf einfache Weise auf dem GlassFish-Server bereitstellen.
![]() |
- Überprüfen Sie in den Eigenschaften des EJB-Projekts die Ausführungsoptionen [1].
- Geben Sie in [2] den Namen des Servers ein, auf dem das EJB bereitgestellt werden soll
- Auf der Registerkarte [Services] [3] wird der Vorgang gestartet [4].
![]() |
- in [5], sobald der GlassFish-Server gestartet ist. Er verfügt noch über kein EJB-Modul.
- Starten Sie den Server MySQL und stellen Sie sicher, dass die Datenbank [dbrdvmedecins] online ist. Dazu können Sie die in Abschnitt 4.5 erstellte NetBeans-Verbindung verwenden.
- Auf der Registerkarte [Projects] [6] wird das EJB-Modul [7] bereitgestellt: SGBD und MySQL5 müssen gestartet sein, damit die vom EJB verwendete Ressource JDBC „jdbc/dbrdvmedecins“ zugänglich ist.
- In [8] erscheint das bereitgestellte EJB in der Baumstruktur des GlassFish-Servers
![]() |
- In [9] wird das bereitgestellte EJB entfernt
- In [10] erscheint das EJB nicht mehr in der Verzeichnisstruktur des GlassFish-Servers.
4.8. Bereitstellung des EJB der Schicht [dao] mit GlassFish
Hier zeigen wir, wie man ein EJB aus seinem .jar-Archiv auf dem GlassFish-Server bereitstellt.
- Starten Sie den Server MySQL und stellen Sie sicher, dass die Datenbank [dbrdvmedecins] online ist. Dazu können Sie die in Abschnitt 4.5 erstellte NetBeans-Verbindung verwenden.
Zur Erinnerung: Die JPA-Konfiguration des EJB-Moduls, das bereitgestellt werden soll, erfolgt in der Datei [persistence.xml]:
Zeile 5 gibt an, dass die JPA-Schicht die Datenquelle JTA, c.a.d verwendet, die vom EJB3-Container verwaltet wird und den Namen „jdbc/dbrdvmedecins“ trägt.
In Abschnitt 4.5 haben wir gesehen, wie diese Ressource JDBC mit NetBeans erstellt wird. Hier zeigen wir, wie dies direkt mit GlassFish erfolgt. Wir folgen dabei einer Vorgehensweise, die in Abschnitt 13.1.2, Seite 79 von [ref1] beschrieben ist.
Zunächst löschen wir die Ressource, um sie neu anlegen zu können. Dies führen wir über NetBeans durch:
![]() |
- in [1], die Ressourcen JDBC des GlassFish-Servers
- in [2], die Ressource „jdbc/dbrdvmedecins“ unseres EJB
- in [3], den Verbindungspool dieser Ressource JDBC
![]() |
- in [4]; der Verbindungspool wird gelöscht. Dies hat zur Folge, dass alle Ressourcen JDBC, die ihn nutzen, gelöscht werden, also die Ressource „jdbc/dbrdvmedecins“.
- In [5] und [6] wurden die Ressource JDBC und der Verbindungspool gelöscht.
Nun verwenden wir die Verwaltungskonsole des GlassFish-Servers, um die Ressource JDBC anzulegen und das EJB bereitzustellen.
![]() |
- auf der Registerkarte „[services] [1]“ in NetBeans, starten Sie den GlassFish-Server „[2]“ und rufen Sie anschließend die Verwaltungskonsole unter „[3]“ auf
- unter [4], melden Sie sich als Administrator an (Passwort: adminadmin, sofern Sie dieses bei der Installation oder danach nicht geändert haben).
![]() |
- in [5], wählen Sie den Zweig [Connection Pools] der GlassFish-Ressourcen
- Erstellen Sie unter [6] einen neuen Verbindungspool. Zur Erinnerung: Ein Verbindungspool ist eine Technik, um die Anzahl der Öffnungen und Schließungen von Verbindungen mit einem SGBD zu begrenzen. Beim Start des Servers N werden eine konfigurationsabhängige Anzahl von Verbindungen zum SGBD geöffnet. Diese offenen Verbindungen werden anschließend den EJBs zur Verfügung gestellt, die sie anfordern, um eine Operation mit dem SGBD durchzuführen. Sobald diese abgeschlossen ist, gibt das EJB die Verbindung an den Pool zurück. Die Verbindung wird niemals geschlossen. Sie wird von den verschiedenen Threads gemeinsam genutzt, die auf den SGBD
- in [7]; geben Sie dem Pool
- in [8]; die Klasse, die die Datenquelle modelliert, ist die Klasse [javax.sql.DataSource]
- in [9], das SGBD, das die Datenquelle enthält, ist hier MySQl.
- in [10]: Fahren Sie mit dem nächsten Schritt fort
![]() |
- Bei [11] sorgt das Attribut „Connection Validation Required“ dafür, dass der Pool vor der Zuweisung einer Verbindung überprüft, ob diese betriebsbereit ist. Ist dies nicht der Fall, erstellt er eine neue Verbindung. Dadurch kann eine Anwendung nach einer vorübergehenden Unterbrechung der Verbindung mit SGBD weiterlaufen. Während der Unterbrechung ist keine Verbindung nutzbar, und es werden Ausnahmen an den Client weitergeleitet. Sobald die Unterbrechung beendet ist, erhalten Clients, die weiterhin Verbindungen anfordern, diese wieder: Dank des Attributs „Connection Validation Required“ werden alle Verbindungen des Pools neu erstellt. Ohne dieses Attribut würde der Pool zwar feststellen, dass die ursprünglichen Verbindungen unterbrochen wurden, aber nicht versuchen, neue zu erstellen.
- In [12] wird die Isolationsstufe „Read Committed“ für Transaktionen angefordert. Diese Stufe stellt sicher, dass eine Transaktion T2 keine Daten lesen kann, die von einer Transaktion T1 geändert wurden, solange diese nicht vollständig abgeschlossen ist.
- In [13] wird festgelegt, dass alle Transaktionen die in [12] angegebene Isolationsstufe verwenden sollen.
![]() |
- Geben Sie in [14] und [15] die URL von BD an, dessen Pool die Verbindungen verwaltet
- in [16], der Benutzer lautet root
- Fügen Sie in [17] eine Eigenschaft hinzu
- in [18] fügen Sie die Eigenschaft „Password“ mit dem Wert () hinzu in [19]. Auch wenn der Screenshot [19] dies nicht zeigt, darf keine leere Zeichenfolge eingegeben werden, sondern es muss () (öffnende Klammer, schließende Klammer) stehen, um ein leeres Passwort anzugeben. Wenn der Benutzer root Ihrer SGBD MySQL ein nicht leeres Passwort hat, geben Sie dieses Passwort ein.
- in [20], schließen Sie den Assistenten zur Erstellung des Verbindungspools für die Datenbank MySQL [dbrdvmedecins] ab.
![]() |
- in [21]: Der Pool wurde erstellt. Klicken Sie auf den entsprechenden Link.
- In [22] ermöglicht die Schaltfläche [Ping] das Herstellen einer Verbindung zur Datenbank [dbrdvmedecins]
- In [23] erscheint, wenn alles geklappt hat, eine Meldung, dass die Verbindung erfolgreich hergestellt wurde
Sobald der Verbindungspool erstellt ist, kann eine JDBC-Ressource angelegt werden:
![]() |
- in [1]. Wählen Sie den Zweig [JDBC Resources] aus dem Objektbaum des Servers aus
- in [2] wird eine neue Ressource JDBC angelegt
- In [3] wird der Ressource JDBC ein Name zugewiesen. Dieser muss mit dem Namen übereinstimmen, der in der Datei [persistence.xml] verwendet wird:
- In [4] wird der Verbindungspool angegeben, den die neue Ressource JDBC verwenden soll: der soeben erstellte
- In [5] schließen Sie den Assistenten zur Erstellung ab
![]() |
- in [6] die neue Ressource JDBC
Nachdem die Ressource JDBC nun erstellt ist, kann das JAR-Archiv des EJB bereitgestellt werden:
![]() |
- in [1], wählen Sie den Zweig [Enterprise Applications]
- in [2], und geben Sie über die Schaltfläche [Deploy] an, dass Sie eine neue Anwendung bereitstellen möchten
- Geben Sie in [3] an, dass es sich bei der Anwendung um ein EJB-Modul handelt
- Wählen Sie unter „[4]“ die JAR-Datei des EJB-Moduls „[serveur-ejb-dao-jpa-hibernate.jar]“ aus, die Ihnen für „TP“ bereitgestellt wurde.
- In [5] können Sie den Namen des EJB-Moduls nach Belieben ändern
- In [6] schließen Sie den Assistenten für die Bereitstellung des EJB-Moduls ab
![]() |
- In [7] wurde das EJB-Modul bereitgestellt. Es kann nun verwendet werden.
4.9. Tests des EJBs der Schicht [dao]
Nachdem das EJB der Schicht [dao] unserer Anwendung nun bereitgestellt wurde, können wir es testen. Dazu verwenden wir den folgenden Java-Client:
![]() |
Die Klasse [MainTestsDaoRemote] [1] ist eine Testklasse JUnit 4. Die Bibliotheken in [2] bestehen zum einen aus:
- der JAR-Datei des EJB der Schicht [dao] [3] (siehe Abschnitt 4.6.4).
- den GlassFish-Bibliotheken [4], die für die Remote-Clients der EJBs erforderlich sind.
Die Testklasse lautet wie folgt:
- Zeile 13: Beachten Sie die Instanziierung des Proxys des entfernten EJB. Es wird dessen Name JNDI „rdvmedecins.dao“ verwendet.
- Die Testmethoden nutzen die vom EJB bereitgestellten Methoden (siehe Abschnitt 4.6.4).
Wenn alles gut läuft, sollten die Tests erfolgreich sein:
![]() |
Nachdem das EJB der Schicht [dao] nun betriebsbereit ist, kann man mit seiner öffentlichen Bereitstellung über einen Webdienst fortfahren.
4.10. Der Webdienst der Schicht [dao]
Eine kurze Einführung in das Konzept der Webdienste finden Sie in Abschnitt 14, Seite 111 von [ref1].
Kehren wir nun zur Serverarchitektur unserer Client-Server-Anwendung zurück:
![]() |
Wir befassen uns oben mit dem Webdienst der Schicht [dao]. Die einzige Aufgabe dieses Dienstes besteht darin, die Schnittstelle des EJB der Schicht [dao] für plattformübergreifende Clients verfügbar zu machen, die mit einem Webdienst kommunizieren können.
Zur Erinnerung: Es gibt zwei Möglichkeiten, einen Webdienst zu implementieren:
- über eine mit @WebService annotierte Klasse, die in einem Web-Container ausgeführt wird
![]() |
- über ein mit @WebService annotiertes EJB, das in einem EJB-Container ausgeführt wird
![]() |
Wir verwenden hier die erste Lösung. In NetBeans müssen wir ein Unternehmensprojekt mit zwei Modulen erstellen:
- das EJB-Modul, das im EJB-Container ausgeführt wird: das EJB der Schicht [dao].
- das Web-Modul, das im Web-Container ausgeführt wird: der Webdienst, den wir gerade erstellen.
Wir werden dieses Unternehmensprojekt auf zwei Arten erstellen.
4.10.1. NetBeans-Projekt – Version 1
Zunächst erstellen wir ein NetBeans-Projekt vom Typ „Webanwendung“:
![]() |
- In [1] erstellen wir ein neues Projekt in der Kategorie „Java Web“ ([2]) vom Typ „Webanwendung“ ([3]).
![]() |
- In [4] wird dem Projekt ein Name gegeben und in [5] wird der Ordner angegeben, in dem es generiert werden soll
- In [6] wird der Anwendungsserver festgelegt, auf dem die Webanwendung ausgeführt werden soll
- In [7] wird der Anwendungskontext festgelegt
- In [8] wird die Projektkonfiguration bestätigt.
![]() |
- In [9] wird das generierte Projekt erstellt. Der von uns erstellte Webdienst wird die EJB aus dem vorherigen Projekt [10] verwenden. Daher muss er auf die .jar-Datei des EJB-Moduls [10] verweisen.
- In [11] fügen wir ein NetBeans-Projekt zu den Bibliotheken des Webprojekts [12] hinzu
![]() |
- In [13] wählt man den Ordner des EJB-Moduls im Dateisystem aus und bestätigt die Auswahl.
![]() |
- In [14] wurde das EJB-Modul zu den Bibliotheken des Webprojekts hinzugefügt.
In [15] implementieren wir den Webdienst mit der folgenden Klasse [WsDaoJpa]:
- In Zeile 4 implementiert die Klasse [WsdaoJpa] die Schnittstelle [IDao]. Zur Erinnerung: Diese Schnittstelle ist im EJB-Archiv der Schicht [dao] in folgender Form definiert:
- Zeile 3: Die Annotation @WebService macht die Klasse [WsDaoJpa] zu einem Webdienst.
- Zeilen 6–7: Die Referenz des EJB der Schicht [dao] wird vom Anwendungsserver in das Feld in Zeile 7 eingefügt. Zur Erinnerung: Es wird immer die lokale Implementierung (hier IDaoLocal) auf diese Weise injiziert. Diese Injektion ist möglich, da der Webdienst in derselben JVM wie das EJB ausgeführt wird.
- Alle Methoden des Webdienstes sind mit der Annotation @WebMethod versehen, um sie für Remote-Clients sichtbar zu machen. Eine Methode, die nicht mit der Annotation @WebMethod versehen ist, wäre intern für den Webdienst und für Remote-Clients nicht sichtbar. Jede Methode M des Webdienstes ruft lediglich die entsprechende Methode M des in Zeile 7 injizierten EJB auf.
Die Erstellung dieses Webdienstes spiegelt sich in einem neuen Zweig im NetBeans-Projekt wider:
![]() |
In [1] ist der Webdienst WsDaoJpa zu sehen, und in [2] die Methoden, die er für Remote-Clients bereitstellt.
Zur Erinnerung: Die Architektur des im Aufbau befindlichen Webdienstes sieht wie folgt aus:
![]() |
Die Komponenten des Webdienstes, die wir bereitstellen werden, sind:
- [1]: das Webmodul, das wir gerade erstellt haben
- [2]: das EJB-Modul, das wir in einem früheren Schritt erstellt haben und von dem der Webdienst abhängt
Um sie gemeinsam bereitzustellen, müssen die beiden Module in einem sogenannten „Enterprise“-Projekt in NetBeans zusammengefasst werden:
![]() |
In [1] erstellen wir ein neues Unternehmensprojekt [2, 3].
![]() |
- In [4,5] benennen wir das Projekt und legen den Erstellungsordner fest
- In [6] wählt man den Anwendungsserver aus, auf dem die Unternehmensanwendung bereitgestellt werden soll
- In [7] kann ein Unternehmensprojekt drei Komponenten umfassen: Webanwendung, EJB-Modul, Client-Anwendung. Hier wird das Projekt ohne Komponenten angelegt. Diese werden zu einem späteren Zeitpunkt hinzugefügt.
![]() |
- In [8] die neu erstellte Unternehmensanwendung.
![]() |
- In [9] mit der rechten Maustaste auf [Java EE Modules] klicken und ein neues Modul hinzufügen
- in [10] werden nur die derzeit in IDE geöffneten NetBeans-Module angezeigt. Hier wählen wir das von uns erstellte Web-Modul [serveur-webservice-1-ejb-dao-jpa-hibernate] und das EJB-Modul [serveur-ejb-dao-jpa-hibernate] aus.
- In [11] sind die beiden Module, die dem Unternehmensprojekt hinzugefügt wurden.
Nun müssen wir diese Unternehmensanwendung noch auf dem GlassFish-Server bereitstellen. Anschließend muss SGBD MySQL gestartet werden, damit auf die vom EJB-Modul verwendete Datenquelle JDBC „jdbc/dbrdvmedecins“ zugegriffen werden kann.
![]() |
- In [1] wird der Glassfish-Server gestartet
- Wenn das EJB-Modul [serveur-ejb-dao-jpa-hibernate] bereitgestellt ist, wird es entladen: [2]
- in [3] wird die Unternehmensanwendung bereitgestellt
![]() |
- in [4], sie ist bereitgestellt. Man sieht, dass sie beide Module enthält: Web und EJB.
4.10.2. NetBeans-Projekt – Version 2
Wir zeigen nun, wie der Webdienst bereitgestellt wird, wenn der Quellcode des EJB-Moduls nicht vorliegt, sondern nur dessen .jar-Archiv.
Das neue NetBeans-Projekt für den Webdienst sieht wie folgt aus:
![]() |
Die wichtigsten Elemente des Projekts sind folgende:
- [1]: Der Webdienst wird durch ein NetBeans-Projekt vom Typ [Web Application] implementiert.
- [2]: Der Webdienst wird durch die bereits behandelte Klasse [WsDaoJpa] implementiert
- [3]: Das EJB-Archiv der Schicht [dao], das der Klasse [WsDaoJpa] den Zugriff auf die Definitionen der verschiedenen Klassen, Schnittstellen und Entitäten der Schichten [dao] und [jpa] ermöglicht.
Anschließend erstellen wir das für die Bereitstellung des Webdienstes erforderliche Unternehmensprojekt:
![]() |
- [1]: Wir erstellen eine Unternehmensanwendung [ea-rdvmedecins], zunächst ohne Module.
- In [2] fügen wir das vorherige Webmodul [serveur-webservice-ejb-dao-jpa-hibernate] hinzu
- in [3] das Ergebnis.
In dieser Form kann die Unternehmensanwendung [ea-rdvmedecins] nicht von NetBeans aus auf dem GlassFish-Server bereitgestellt werden. Es tritt ein Fehler auf. Daher muss das EAR-Archiv der Anwendung [ea-rdvmedecins] manuell bereitgestellt werden:
![]() |
- Das Archiv [ea-rdvmedecins.ear] befindet sich im Ordner [dist] [2] auf der Registerkarte [Files] in NetBeans.
- In diesem Archiv „[3]“ befinden sich die beiden Elemente der Unternehmensanwendung:
- das EJB-Archiv [serveur-ejb-dao-jpa-hibernate]. Dieses Archiv ist vorhanden, da es zu den vom Webdienst referenzierten Bibliotheken gehörte.
- das Webdienst-Archiv [serveur-webservice- ejb-dao-jpa-hibernate].
- Das Archiv [ea-rdvmedecins.ear] wird aus einem einfachen Build und [4] der Unternehmensanwendung erstellt.
- Bei [5] schlägt der Bereitstellungsvorgang fehl.
Um das Archiv [ea-rdvmedecins.ear] der Unternehmensanwendung bereitzustellen, gehen wir so vor, wie es bei der Bereitstellung des EJB-Archivs [serveur-ejb-dao-jpa-hibernate.jar] in Abschnitt 4.2 gezeigt wurde. Wir verwenden erneut den Web-Verwaltungsclient des GlassFish-Servers. Bereits beschriebene Schritte werden nicht wiederholt.
Zunächst „entfernen“ wir die in Abschnitt 4.10.1 bereitgestellte Unternehmensanwendung:
![]() |
- [1]: Wählen Sie den Zweig [Enterprise Applications] des GlassFish-Servers aus
- Wählen Sie unter [2] die zu entladende Unternehmensanwendung aus und entladen Sie sie dann unter [3]
- In [4] wurde die Unternehmensanwendung entladen
![]() |
- in [1] wählen Sie den Zweig [Enterprise Applications] des Glassfish-Servers aus
- in [2], stellen Sie eine neue Unternehmensanwendung bereit
- in [3], wählen Sie den Typ [Enterprise Application]
- unter [4] geben Sie die .ear-Datei des NetBeans-Projekts an: [ea-rdvmedecins]
- in [5]: Stellen Sie dieses Archiv bereit
![]() |
- in [6] bereitgestellt, die Anwendung wurde bereitgestellt
- in [7], der Webdienst [WsDaoJpa] erscheint im Zweig [Web Services] des GlassFish-Servers. Wählen Sie ihn aus.
- Unter [8] erhält man verschiedene Informationen zum Webdienst. Für einen Kunden ist die Information [9] am interessantesten: die URI des Webdienstes.
- Unter [10] kann der Webdienst getestet werden
![]() |
- Unter [11], der URI des Webdienstes , wurde der Parameter ?tester hinzugefügt. Diese URI zeigt eine Testseite an. Alle vom Webdienst bereitgestellten Methoden (@WebMethod) werden angezeigt und können getestet werden. Hier wird die Methode [13] getestet, die die Liste der Kunden abfragt.
![]() |
- Bei [14] zeigen wir nur einen Ausschnitt der Antwortseite. Es ist jedoch ersichtlich, dass die Methode getAllClients die Kundenliste tatsächlich zurückgegeben hat. Der Screenshot zeigt, dass sie ihre Antwort im Format XML sendet.
Ein Webdienst wird vollständig durch eine Datei namens XML beschrieben, die als WSDL bezeichnet wird:
![]() |
- in [1] im Web-Verwaltungstool des Glassfish-Servers wählen Sie den Webdienst [WsDaoJpa]
- in [2], folgen Sie dem Link [View WSDL]
![]() |
- in [3]: Die URI der Datei WSDL. Diese Information ist wichtig und muss bekannt sein. Sie wird benötigt, um die Clients dieses Webdienstes zu konfigurieren.
- in [4], die Beschreibung XML des Webdienstes. Wir werden diesen komplexen Inhalt nicht näher erläutern.
4.10.3. Tests JUnit des Webdienstes
Wir erstellen ein NetBeans-Projekt, um die bereits mit einem EJB-Client durchgeführten Tests nun mit einem Client für den kürzlich bereitgestellten Webdienst zu „wiederholen“. Dabei verfolgen wir einen ähnlichen Ansatz wie den in Abschnitt 14.2.1, Seite 115 von [ref1] beschriebenen.
![]() |
- in [1], ein klassisches Java-Projekt
- in [2], die Testklasse
- in [3]: Der Client nutzt das EJB-Archiv, um Zugriff auf die Definitionen der Schnittstelle der Schicht [dao] und der JPA-Entitäten zu erhalten. Zur Erinnerung: Dieses Archiv befindet sich im Unterordner [dist] des EJB-Modulordners.
Um auf den Remote-Webdienst zuzugreifen, müssen Proxy-Klassen generiert werden:
![]() |
In dem obigen Schema kommuniziert die Schicht [2] [C=Client] mit der Schicht [1] [S=Serveur]. Um mit der Schicht [S] zu kommunizieren, muss der Client [C] eine Netzwerkverbindung zur Schicht [S] herstellen und mit dieser gemäß einem bestimmten Protokoll kommunizieren. Bei den Netzwerkverbindungen handelt es sich um TCP, und das Transportprotokoll ist HTTP. Die Schicht [S], die den Webdienst darstellt, wird durch ein Java-Servlet implementiert, das vom Glassfish-Server ausgeführt wird. Wir haben dieses Servlet nicht selbst geschrieben. Seine Generierung erfolgt automatisch durch Glassfish anhand der Annotationen @Webservice und @WebMethod der von uns geschriebenen Klasse [WsDaoJpa]. Ebenso werden wir die Generierung der Client-Schicht [C] automatisieren. Die Schicht [C] wird manchmal als Proxy-Schicht des entfernten Webdienstes bezeichnet, wobei der Begriff proxy ein Zwischenelement in einer Softwarekette bezeichnet. Hier ist der C-Proxy das Zwischenelement zwischen dem Client, den wir schreiben werden, und dem Webdienst, den wir bereitgestellt haben.
Mit NetBeans 6.5 lässt sich der Proxy C wie folgt generieren (im weiteren Verlauf muss der Webdienst auf dem GlassFish-Server aktiv sein):
![]() |
- in [1], fügen Sie dem Java-Projekt ein neues Element hinzu
- in [2] den Zweig [Web services] auswählen
- in [3]: Wählen Sie [Web Service Client] aus
![]() |
- in [4] die URI der Datei WSDL des Webdienstes angeben. Diese URI wurde in Abschnitt 4.10.2 vorgestellt.
- bei [5] den Standardwert [JAX-WS] beibehalten. Der andere mögliche Wert ist [JAX-RPC]
- Nach dem Bestätigen des Assistenten zur Erstellung des Webdienst-Proxys wurde das NetBeans-Projekt um einen Zweig [Web Service References] [6] erweitert. Dieser Zweig zeigt die vom Remote-Webdienst bereitgestellten Methoden an.
![]() |
- Auf der Registerkarte [Files] [7] wurde Java-Quellcode hinzugefügt ([8]). Dieser entspricht dem generierten C-Proxy.
- In [9] ist der Code einer der Klassen zu sehen. Dort ist zu erkennen, dass sie in einem Paket abgelegt wurden. Wir werden den Code dieser Klassen nicht näher erläutern, da er wiederum recht komplex ist.
Für den Java-Client, den wir gerade erstellen, dient der generierte C-Proxy als Vermittler. Um auf die Methode M des entfernten Webdienstes zuzugreifen, ruft der Java-Client die Methode M des C-Proxys auf. Der Java-Client ruft somit lokale Methoden auf (die in derselben JVM ausgeführt werden), und für ihn transparent werden diese lokalen Aufrufe in entfernte Aufrufe übersetzt.
Nun müssen wir noch lernen, wie man die Methoden M des C-Proxys aufruft. Kehren wir zu unserer Testklasse JUnit zurück:
![]() |
In [1] ist die Testklasse [MainTestsDaoRemote] dieselbe, die bereits beim Test des EJB der Schicht [dao] verwendet wurde:
- In Zeile [13] bleibt der Test test1 unverändert erhalten.
- Zeile [9]: Der Inhalt der Methode [init] wurde gelöscht.
Derzeit weist das Projekt Fehler auf, da die Testmethode [test1] die Entitäten [Client], [Medecin], [Creneau], [Rv] verwendet, die sich nicht mehr in denselben Paketen wie zuvor befinden. Sie befinden sich im Paket des generierten C-Proxys. Die betroffenen Anweisungen import werden gelöscht und über den Vorgang „Fix Imports“ neu generiert.
![]() |
Kehren wir zum Code der Testklasse [MainTestsDaoRemote] zurück:
Die Methode [init] in Zeile 10 muss die Referenz auf die Schicht [dao] in Zeile 7 initialisieren. Wir müssen wissen, wie wir den generierten C-Proxy in unserem Code verwenden können. NetBeans unterstützt uns dabei.
![]() |
- Wählen Sie in [1] die Methode [getAllClients] des Webdienstes aus und ziehen Sie diese Methode mit der Maus in die Methode [init] der Testklasse.
Das Ergebnis lautet [2]. Dieses Code-Gerüst zeigt uns, wie der generierte C-Proxy verwendet wird:
- Die Zeile [5] zeigt, dass die Methode [getAllClients] eine Methode des Objekts vom Typ [WsDaoJpa] ist, das in Zeile 3 definiert wurde. Der Typ [WsDaoJpa] ist eine Schnittstelle, die dieselben Methoden aufweist wie die vom Remote-Webdienst bereitgestellten.
- In Zeile [3] wird das Objekt [WsDaoJpa port] aus einem anderen Objekt vom Typ [WsDaoJpaService] abgerufen, das in Zeile 2 definiert ist. Der Typ [WsDaoJpaService] stellt den lokal generierten C-Proxy dar.
- Der Zugriff auf den Remote-Webdienst kann fehlschlagen, daher ist der gesamte Code von einer try/catch-Anweisung umgeben.
- Die Objekte des C-Proxys befinden sich im Paket [rdvmedecins.ws]
Wenn man diesen Code verstanden hat, wird deutlich, dass die lokale Referenz des Remote-Webdienstes mit folgendem Code abgerufen werden kann:
Der Code der Testklasse JUnit lautet dann wie folgt:
Nun sind wir bereit für die Tests:
![]() |
In [1] wird der Test JUnit ausgeführt. In [2] ist er erfolgreich. Betrachtet man die Ausgaben in der NetBeans-Konsole, findet man Zeilen wie die folgenden:
Liste des clients :
rdvmedecins.ws.Client@1982fc1
rdvmedecins.ws.Client@676437
rdvmedecins.ws.Client@1e4853f
rdvmedecins.ws.Client@1e808ca
Auf der Serverseite verfügt die Entität [Client] über eine Methode toString, die die verschiedenen Felder eines Objekts vom Typ [Client] anzeigt. Bei der automatischen Generierung des C-Proxys werden die Entitäten im C-Proxy erstellt, jedoch nur mit den privaten Feldern und den dazugehörigen get-/set-Methoden. Daher wurde die Methode toString in der Entität [Client] des C-Proxys nicht generiert. Dies erklärt die zuvor gezeigte Ausgabe. Dies ändert nichts am Test JUnit: Er wurde erfolgreich durchgeführt. Wir gehen nun davon aus, dass ein funktionsfähiger Webdienst vorliegt.






























































































