4. Der J2EE-Webservice für Termine
Kehren wir zur Architektur der zu erstellenden Anwendung zurück:
![]() |
In diesem Abschnitt konzentrieren wir uns auf die Erstellung des J2EE-Webdienstes [1], der auf einem Sun/Glassfish-Server läuft.
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: die ID-Nummer des Arztes – der Primärschlüssel der Tabelle
- VERSION: Eine Zahl, die die Version der Zeile in der Tabelle angibt. Diese Zahl wird bei jeder Änderung an der Zeile um 1 erhöht.
- LAST_NAME: der Nachname des Arztes
- FIRST_NAME: der Vorname des Arztes
- TITLE: Anrede (Frau, Frau, Herr)
4.1.2. Die Tabelle [CLIENTS]
Die Patienten der verschiedenen Ärzte werden in der Tabelle [CLIENTS] gespeichert:
![]() | ![]() |
- ID: ID-Nummer zur Identifizierung des Kunden – Primärschlüssel der Tabelle
- VERSION: Nummer, die die Version der Zeile in der Tabelle identifiziert. Diese Nummer wird bei jeder Änderung an der Zeile um 1 erhöht.
- LAST NAME: Der Nachname des Kunden
- VORNAME: Der Vorname des Kunden
- TITLE: Anrede (Frau, Frau, Herr)
4.1.3. Die Tabelle [SLOTS]
Sie listet die Zeitfenster auf, in denen Termine verfügbar sind:
![]() |
![]() |
- ID: ID-Nummer für den Zeitblock – Primärschlüssel der Tabelle (Zeile 8)
- VERSION: Eine Zahl, die die Version der Zeile in der Tabelle angibt. Diese Zahl wird bei jeder Änderung an der Zeile um 1 erhöht.
- DOC_ID: ID-Nummer, die den Arzt identifiziert, zu dem dieses Zeitfenster gehört – Fremdschlüssel auf der Spalte DOCTORS(ID).
- START_TIME: Startzeit des Zeitfensters
- MSTART: Startminute des Zeitfensters
- HFIN: Endzeit des Zeitfensters
- MFIN: Endminuten des Zeitfensters
Die zweite Zeile der Tabelle [SLOTS] (siehe [1] oben) gibt beispielsweise an, dass Zeitfenster Nr. 2 um 8:20 Uhr beginnt und um 8:40 Uhr endet und der Ärztin Nr. 1 (Frau Marie PELISSIER) zugeordnet ist.
4.1.4. Die Tabelle [RV]
Sie listet die für jeden Arzt gebuchten Termine auf:
![]() |
- ID: eindeutige Kennung für den Termin – Primärschlüssel
- DAY: Tag des Termins
- SLOT_ID: Terminzeitfenster – Fremdschlüssel auf das Feld [ID] der Tabelle [SLOTS] – bestimmt sowohl das Zeitfenster als auch den beteiligten Arzt.
- CLIENT_ID: ID des Kunden, für den die Reservierung vorgenommen wird – Fremdschlüssel auf das Feld [ID] der Tabelle [CLIENTS]
Diese Tabelle unterliegt einer Eindeutigkeitsbeschränkung für die Werte der verknüpften Spalten (DAY, SLOT_ID):
Wenn eine Zeile in der Tabelle [RV] den Wert (DAY1, SLOT_ID1) für die Spalten (DAY, SLOT_ID) enthält, darf dieser Wert an keiner anderen Stelle vorkommen. Andernfalls würde dies bedeuten, dass zwei Termine zur gleichen Zeit für denselben Arzt gebucht wurden. Aus Sicht der Java-Programmierung löst der JDBC-Treiber der Datenbank in diesem Fall eine SQLException aus.
Die Zeile mit der ID 3 (siehe [1] oben) bedeutet, dass am 23.08.2006 ein Termin für Slot Nr. 20 und Kunde Nr. 4 gebucht wurde. Die Tabelle [SLOTS] gibt an, dass Slot Nr. 20 dem Zeitfenster 16:20 – 16:40 Uhr entspricht und zur Ärztin Nr. 1 (Frau Marie PELISSIER) gehört. Die Tabelle [CLIENTS] gibt an, dass Patient Nr. 4 Frau Brigitte BISTROU ist.
4.2. Erstellung der Datenbank
Erstellen Sie die MySQL-Datenbank [dbrdvmedecins] mit einem Tool Ihrer Wahl. Um die Tabellen zu erstellen und zu füllen, können Sie das bereitgestellte Skript [createbd.sql] verwenden. Sein Inhalt lautet wie folgt:
4.3. Serverseitige Architekturkomponenten
Kehren wir zur Architektur der zu erstellenden Anwendung zurück:
![]() |
Auf der Serverseite wird die Anwendung aus folgenden Komponenten bestehen:
- einer JPA-Schicht, die die Interaktion mit der Datenbank über Objekte ermöglicht
- einem 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 EJB-Schnittstelle in Form eines Webservices für Remote-Clients verfügbar zu machen.
Die Elemente (b) und (c) implementieren die im vorherigen Diagramm dargestellte [DAO]-Schicht. Wir wissen, 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 Webservice verwendet ein standardisiertes Kommunikationsprotokoll, das von verschiedenen Sprachen implementiert wird: .NET, PHP, C++, ... Genau das wollen wir hier anhand eines .NET-Clients demonstrieren.
Eine kurze Einführung in Webdienste finden Sie 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, finden Sie ein Beispiel für die zweite Lösung.
4.4. sowie die Hibernate-Konfiguration für den GlassFish-Server
Je nach Version verfügt der in NetBeans enthaltene GlassFish V2-Server möglicherweise nicht über die von der JPA/Hibernate-Schicht benötigten Hibernate-Bibliotheken. Wenn Sie im weiteren Verlauf des Tutorials feststellen, dass GlassFish keine JPA/Hibernate-Implementierung bereitstellt, oder wenn während der Servicebereitstellung eine Ausnahme auftritt, die darauf hinweist, dass die Hibernate-Bibliotheken nicht gefunden werden können, müssen Sie die Bibliotheken in den Ordner [<glassfish>/domains/domain1/lib/ext] kopieren und anschließend den GlassFish-Server neu starten:
![]() |
|
Die Hibernate-Bibliotheken sind in der ZIP-Datei enthalten, die dem Tutorial beiliegt.
4.5. Die automatischen Generierungstools von NetBeans
Kehren wir zu der Architektur zurück, die wir erstellen müssen:
![]() |
Mit NetBeans ist es möglich, die [JPA]-Schicht und die [EJB]-Schicht, die den Zugriff auf die generierten JPA-Entitäten steuert, automatisch zu generieren. Es ist hilfreich, mit diesen automatischen Generierungsmethoden vertraut zu sein, da der generierte Code wertvolle Einblicke in die Erstellung von JPA-Entitäten oder des EJB-Codes, der diese nutzt, bietet.
Wir werden nun einige dieser automatischen Generierungswerkzeuge beschreiben. Um den generierten Code zu verstehen, benötigen Sie fundierte Kenntnisse über JPA-Entitäten [ref1] und EJBs [ref2].
Erstellen einer NetBeans-Verbindung zur Datenbank
- Starten Sie das DBMS MySQL 5, damit die Datenbank verfügbar ist
- Erstellen Sie eine NetBeans-Verbindung zur Datenbank [dbrdvmedecins]
![]() |
- Wählen Sie auf der Registerkarte [Dateien] im Abschnitt [Datenbanken] [1] den MySQL-JDBC-Treiber [2] aus
- Wählen Sie dann die Option [3] „Verbinden über“, um eine Verbindung zu einer MySQL-Datenbank herzustellen
- Geben Sie unter [4] die erforderlichen Informationen ein
- und bestätigen Sie anschließend in [5]
![]() |
- In [6] wird die Verbindung hergestellt. Sie sehen die vier Tabellen in der verbundenen Datenbank.
![]() |
- Erstellen Sie unter [1] eine neue Anwendung, ein EJB-Modul
- Wählen Sie in [2] die Kategorie [Java EE] und in [3] den Typ [EJB-Modul]
![]() |
- Wählen Sie in [4] einen Ordner für das Projekt aus und geben Sie ihm in [5] einen Namen – schließen Sie dann den Assistenten ab
- In [6] das generierte Projekt
Hinzufügen einer JDBC-Ressource zum GlassFish-Server
Wir fügen dem GlassFish-Server eine JDBC-Ressource hinzu.
![]() |
![]() |
- Starten Sie auf der Registerkarte [Services] den GlassFish-Server [2, 3]
- Klicken Sie auf der Registerkarte [Projekte] mit der rechten Maustaste auf das EJB-Projekt und wählen Sie unter [5] die Option [Neu / Sonstiges], um dem Projekt ein Element hinzuzufügen.

- Wählen Sie unter [6] die Kategorie [GlassFish] aus und geben Sie unter [7] an, dass Sie eine JDBC-Ressource erstellen möchten, indem Sie den Typ [JDBC-Ressource] auswählen
- Geben Sie unter [8] an, dass diese JDBC-Ressource einen eigenen Verbindungspool verwenden soll.
- Geben Sie in [9] der JDBC-Ressource einen Namen
- In [10] fahren Sie mit dem nächsten Schritt fort
![]() |
- Definieren Sie in [11] die Eigenschaften des Verbindungspools der JDBC-Ressource
- Geben Sie in [12] dem Verbindungspool einen Namen
- Wählen Sie in [13] die zuvor erstellte NetBeans-Verbindung [dbrdvmedecins] aus
- Fahren Sie in [14] mit dem nächsten Schritt fort
- In [15] gibt es auf dieser Seite normalerweise nichts zu ändern. Die Eigenschaften der Verbindung zur MySQL-Datenbank [dbrdvmedecins] wurden von denen der zuvor erstellten NetBeans-Verbindung [dbrdvmedecins] übernommen
- Fahren Sie in [16] mit dem nächsten Schritt fort
![]() |
- Behalten Sie in [17] die vorgegebenen Standardwerte bei
- in [18] und schließen Sie den Assistenten ab. Dadurch wird die Datei [sun-resources.xml] [19] mit folgendem Inhalt erstellt:
Die obige Datei enthält alle im Assistenten eingegebenen Informationen im XML-Format. Sie wird von der NetBeans-IDE verwendet, um den GlassFish-Server anzuweisen, die in Zeile 4 definierte Ressource „jdbc/dbrdvmedecins“ zu erstellen.
Erstellen einer Persistenz-Einheit
Die Persistenz-Einheit [persistence.xml] konfiguriert die JPA-Schicht: Sie gibt die verwendete JPA-Implementierung an (TopLink, Hibernate usw.) und konfiguriert diese.
![]() |
![]() |
- Klicken Sie in [1] mit der rechten Maustaste auf das EJB-Projekt und wählen Sie in [2] [Neu / Sonstiges]
- Wählen Sie in [3] die Kategorie [Persistenz] aus und geben Sie dann in [4] an, dass Sie eine JPA-Persistenz-Einheit erstellen möchten
![]() |
- Geben Sie in [5] der erstellten Persistenz-Einheit einen Namen
- Wählen Sie in [6] [Hibernate] als JPA-Implementierung aus
- Wählen Sie in [7] die soeben erstellte GlassFish-Ressource „jdbc/dbrdvmedecins“ aus
- Geben Sie in [8] an, dass beim Instanziieren der JPA-Schicht keine Aktion an der Datenbank durchgeführt werden soll
- Schließen Sie den Assistenten ab
- In [9] wird die vom Assistenten erstellte Datei [persistence.xml] angezeigt
Ihr Inhalt lautet wie folgt:
Auch hier werden die im Assistenten eingegebenen Informationen in das XML-Format konvertiert. Diese Datei reicht für die Arbeit mit der MySQL5-Datenbank „dbrdvmedecins“ nicht aus. Wir müssten Hibernate den Typ des zu verwaltenden DBMS mitteilen. Dies wird später erfolgen.
![]() |
![]() |
![]() |
- Klicken Sie in [1] mit der rechten Maustaste auf das Projekt und wählen Sie in [2] die Option [Neu / Sonstiges]
- Wählen Sie in [3] die Kategorie [Persistenz] aus und geben Sie dann in [4] an, dass Sie JPA-Entitäten aus einer bestehenden Datenbank erstellen möchten.
![]() |
- Wählen Sie in [5] die von uns erstellte JDBC-Quelle „jdbc/dbrdvmedecins“ aus
- Wählen Sie in [6] die vier Tabellen aus der zugehörigen Datenbank aus
- Fügen Sie in [7,8] alle diese Tabellen in die Generierung der JPA-Entitäten ein
- Fahren Sie in [9] mit dem Assistenten fort
![]() |
- In [10] die JPA-Entitäten, die generiert werden sollen
- in [11] benennen Sie das Paket für die JPA-Entitäten
- in [12] den Java-Typ auswählen, der die von der JPA-Schicht zurückgegebenen Objektlisten kapseln soll
- Beenden Sie den Assistenten
- in [13] die vier generierten JPA-Entitäten, eine für jede Datenbanktabelle.
Hier ist zum Beispiel der Code für die [Rv]-Entität, die eine Zeile in der [rv]-Tabelle der Datenbank [dbrdvmedecins] darstellt.
Erstellen der EJB-Schicht für den Zugriff auf JPA-Entitäten
![]() |
![]() |
- Klicken Sie in [1] mit der rechten Maustaste auf das Projekt und wählen Sie in [2] die Option [Neu / Sonstiges]
- Wählen Sie in [3] die Kategorie [Persistenz] und anschließend in [4] den Typ [Session Beans für Entity-Klassen]
![]() |
- In [5] werden die zuvor erstellten JPA-Entitäten angezeigt
- Wählen Sie in [6] alle aus
- In [7] sind sie ausgewählt
- Fahren Sie in [8] mit dem Assistenten fort
![]() |
- Geben Sie in [9] einen Namen für das Paket der zu generierenden EJBs ein
- Geben Sie in [10] an, dass die EJBs sowohl eine lokale als auch eine Remote-Schnittstelle implementieren müssen
- Schließen Sie den Assistenten ab
- In [11] werden die generierten EJBs
Hier ist beispielsweise der EJB-Code, der den Zugriff auf die Entität [Rv] und damit auf die Tabelle [rv] in der Datenbank [dbrdvmedecins] verwaltet:
Wie bereits erwähnt, kann die automatische Codegenerierung sehr nützlich sein, um ein Projekt zu starten und sich mit JPA-Entitäten und EJBs vertraut zu machen. In den folgenden Abschnitten werden wir die JPA- und EJB-Schichten mit unserem eigenen Code neu schreiben, aber der Leser wird Informationen wiedererkennen, die wir gerade bei der automatischen Generierung der Schichten behandelt haben.
4.6. Das NetBeans-Projekt für das EJB-Modul
Wir erstellen ein neues leeres EJB-Modul (siehe Abschnitt 4.5):
![]() |
- Das Paket [rdvmedecins.entities] enthält die Entitäten der JPA-Schicht
- Das Paket [rdvmedecins.dao] implementiert das EJB für die [dao]-Schicht
- Das Paket [rdvmedecins.exceptions] implementiert eine anwendungsspezifische Ausnahmeklasse
Im Folgenden gehen wir davon aus, dass der Leser alle Schritte in Abschnitt 4.5 befolgt hat. Einige davon müssen wiederholt werden.
4.6.1. Konfigurieren der JPA-Schicht
Sehen wir uns die Architektur unserer Client/Server-Anwendung noch einmal an:
![]() |
Das NetBeans-Projekt:
![]() |
Die [JPA]-Schicht wird durch die oben genannten Dateien [persistence.xml] und [sun-resources.xml] konfiguriert. Diese beiden Dateien werden von Assistenten generiert, die wir bereits kennengelernt haben:
- Die Generierung 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: Transaktionen werden vom GlassFish-EJB3-Container 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 JTA-Datenquelle hat den JNDI-Namen „jdbc/dbrdvmedecins“.
- Zeile 8: Diese Zeile wird nicht automatisch generiert. Sie muss manuell hinzugefügt werden. Sie teilt Hibernate mit, dass das verwendete DBMS 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 MySQL-Datenbank `dbrdvmedecins` ist die in Abschnitt 4.1 beschriebene.
- Zeile 7: Die Eigenschaften des mit dieser Datenquelle verbundenen Verbindungspools
4.6.2. Die Entitäten der JPA-Schicht
Sehen wir uns die Architektur unserer Client/Server-Anwendung noch einmal an:
![]() |
Das NetBeans-Projekt:
![]() |
Das Paket [rdvmedecins.entites] implementiert die [Jpa]-Schicht.
In Abschnitt 4.5 haben wir gesehen, wie man JPA-Entitäten für eine Anwendung automatisch generiert. 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 enthalten. 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: Beachten Sie, dass die Klasse [Person] selbst keine Entität (@Entity) ist. Sie wird die übergeordnete Klasse von Entitäten sein. Die Annotation @MappedSuperClass weist auf diese Situation hin.
Die Entität [Client] kapselt die Zeilen der Tabelle [clients]. Sie leitet sich von der vorherigen Klasse [Person] ab:
- Zeile 3: Die Klasse [Client] ist eine JPA-Entität
- Zeile 4: Sie ist mit der Tabelle [clients] verknüpft
- Zeile 5: Sie leitet sich von der Klasse [Person] ab
Die Entität [Doctor], die die Zeilen der Tabelle [doctors] kapselt, folgt dem gleichen Muster:
Die Entität [Creneau] kapselt die Zeilen der Tabelle [creneaux]:
- Die Zeilen 15–17 modellieren die „Eins-zu-Viele“-Beziehung zwischen der Tabelle [slots] und der Tabelle [doctors] in der Datenbank.
Die Entität [Rv] kapselt die Zeilen der Tabelle [rv]:
- Die Zeilen 15–17 modellieren die „Eins-zu-Viele“-Beziehung zwischen der Tabelle [rv] und der Tabelle [clients] in der Datenbank, und die Zeilen 18–20 modellieren die „Eins-zu-Viele“-Beziehung zwischen der Tabelle [rv] und der Tabelle [slots]
4.6.3. Die Ausnahmeklasse
![]() |
Die Ausnahmeklasse der Anwendung [ RdvMedecinsException] lautet wie folgt:
- Zeile 6: Die Klasse erweitert die Klasse [RuntimeException]. Daher verlangt der Compiler nicht, dass sie mit try/catch-Blöcken abgefangen wird.
- Zeile 5: Die Annotation @ApplicationException stellt sicher, dass die Ausnahme nicht von einer [EjbException] „verschluckt“ wird.
Um die Annotation @ApplicationException zu verstehen, wollen wir uns noch einmal die serverseitige Architektur ansehen:
![]() |
Die Ausnahme [RdvMedecinsException] wird von den EJB-Methoden in der [dao]-Schicht innerhalb des EJB3-Containers ausgelöst und von diesem abgefangen. Ohne die Annotation @ApplicationException kapselt der EJB3-Container die aufgetretene Ausnahme in einer [EjbException] und löst sie erneut aus. Möglicherweise möchten Sie diese Kapselung nicht und ziehen es vor, eine Ausnahme vom Typ [RdvMedecinsException] aus dem EJB3-Container entweichen zu lassen. Genau das ermöglicht die Annotation @ApplicationException. Darüber hinaus weist das Attribut (rollback=true) dieser Annotation den EJB3-Container an, dass die Transaktion zurückgesetzt werden muss, wenn eine Ausnahme vom Typ [RdvMedecinsException] innerhalb einer Methode auftritt, die als Teil einer Transaktion mit einem DBMS ausgeführt wird. In der Fachsprache wird dies als „Rollback der Transaktion“ bezeichnet.
4.6.4. Die EJB der [dao]-Schicht
![]() |
![]() |
Die Java-Schnittstelle [ IDao] der [dao]-Schicht sieht wie folgt aus:
Die lokale Schnittstelle des EJB [IDaoLocal] erweitert lediglich die vorherige Schnittstelle [IDao]:
Das Gleiche gilt für die Remote-Schnittstelle [IDaoRemote]:
Das EJB [DaoJpa] implementiert sowohl die lokale als auch die Remote-Schnittstelle:
- Zeile 3 gibt an, dass das 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 Remote-Schnittstellen implementiert.
Der vollständige EJB-Code 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 EntityManager-Objekt, 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: JPQL-Abfrage, die alle Zeilen aus der Tabelle [clients] als Liste von [Client]-Objekten zurückgibt.
- Zeile 22: Eine ähnliche Abfrage für Ärzte
- Zeile 32: Eine JPQL-Abfrage, die eine Verknüpfung zwischen den Tabellen [slots] und [doctors] durchführt. Sie wird durch die ID des Arztes parametrisiert.
- Zeile 43: Eine JPQL-Abfrage, die eine Verknüpfung zwischen den Tabellen [appointments], [slots] und [doctors] durchführt und zwei Parameter hat: die ID des Arztes und das Termin-Datum.
- Zeilen 55–57: Erstellung eines Termins und dessen anschließende Speicherung in der Datenbank.
- Zeile 67: Löscht einen Termin aus der Datenbank.
- Zeile 76: Führt eine SELECT-Abfrage in der Datenbank durch, um einen bestimmten Kunden zu finden
- Zeile 85: Dasselbe für einen Arzt
- Zeile 94: dasselbe für einen Termin
- Zeile 103: dasselbe für einen Zeitblock
- Bei allen Operationen, die den Persistenzkontext aus Zeile 9 betreffen, kann es zu einem Problem mit der Datenbank kommen. Daher sind sie alle in einem try/catch-Block eingeschlossen. Jede Ausnahme wird in der benutzerdefinierten Ausnahme RdvMedecinsException gekapselt.
Nach der Kompilierung erzeugt das EJB-Modul eine JAR-Datei mit dem Namen „ “:
![]() |
4.7. Bereitstellung des EJB der [DAO]-Schicht mit NetBeans
Mit NetBeans können Sie das zuvor erstellte EJB ganz einfach auf dem GlassFish-Server bereitstellen.
![]() |
- Aktivieren Sie in den EJB-Projekteigenschaften die Laufzeitoptionen [1].
- Geben Sie unter [2] den Namen des Servers an, auf dem die EJB bereitgestellt werden soll
- Starten Sie es auf der Registerkarte [Services] [3] [4].
![]() |
- In [5] der GlassFish-Server nach dem Start. Er verfügt noch nicht über ein EJB-Modul.
- Starten Sie den MySQL-Server und stellen Sie sicher, dass die Datenbank [dbrdvmedecins] online ist. Dazu können Sie die in Abschnitt 4.5 erstellte NetBeans-Verbindung verwenden.
- Stellen Sie auf der Registerkarte [Projekte] [6] das EJB-Modul [7] bereit: Das DBMS MySQL5 muss laufen, damit die vom EJB verwendete JDBC-Ressource „jdbc/dbrdvmedecins“ zugänglich ist.
- In [8] erscheint das bereitgestellte EJB in der GlassFish-Server-Struktur
![]() |
- Entfernen Sie in [9] das bereitgestellte EJB
- In [10] erscheint die EJB nicht mehr im GlassFish-Serverbaum.
4.8. Bereitstellung des EJB aus der [DAO]-Schicht mit GlassFish
Hier zeigen wir, wie man eine EJB aus ihrem .jar-Archiv auf dem GlassFish-Server bereitstellt.
- Starten Sie den MySQL-Server und stellen Sie sicher, dass die Datenbank [dbrdvmedecins] online ist. Dazu können Sie die in Abschnitt 4.5 erstellte NetBeans-Verbindung verwenden.
Sehen wir uns die JPA-Konfiguration des zu implementierenden EJB-Moduls an. Diese Konfiguration ist in der Datei [persistence.xml] definiert:
Zeile 5 gibt an, dass die JPA-Schicht eine JTA-Datenquelle verwendet, d. h. eine vom EJB3-Container verwaltete Datenquelle mit dem Namen „jdbc/dbrdvmedecins“.
In Abschnitt 4.5 haben wir gesehen, wie man diese JDBC-Ressource mit NetBeans erstellt. Hier zeigen wir, wie man dies direkt mit GlassFish macht. Wir folgen der in Abschnitt 13.1.2, Seite 79 von [ref1] beschriebenen Vorgehensweise.
Zunächst löschen wir die Ressource, damit wir sie neu erstellen können. Dies tun wir über NetBeans:
![]() |
- in [1] die JDBC-Ressourcen des GlassFish-Servers
- in [2] die Ressource „jdbc/dbrdvmedecins“ unseres EJB
- in [3] den Verbindungspool für diese JDBC-Ressource
![]() |
- in [4] löschen wir den Verbindungspool. Dies hat zur Folge, dass alle JDBC-Ressourcen gelöscht werden, die ihn nutzen, einschließlich der Ressource „jdbc/dbrdvmedecins“.
- in [5] und [6] wurden die JDBC-Ressource und der Verbindungspool zerstört.
Nun verwenden wir die GlassFish-Server-Verwaltungskonsole, um die JDBC-Ressource zu erstellen und das EJB bereitzustellen.
![]() |
- Starten Sie in der Registerkarte [Services] [1] von NetBeans den GlassFish-Server [2] und rufen Sie anschließend [3] dessen Verwaltungskonsole auf
- Melden Sie sich in [4] als Administrator an (Passwort: adminadmin, sofern Sie es während der Installation oder danach nicht geändert haben).
![]() |
- Wählen Sie in [5] den Zweig [Connection Pools] der GlassFish-Ressourcen aus
- Erstellen Sie in [6] einen neuen Verbindungspool. Beachten Sie, dass ein Verbindungspool eine Technik zur Begrenzung der Anzahl der mit einem DBMS geöffneten und geschlossenen Verbindungen ist. Beim Start des Servers werden N Verbindungen – eine durch die Konfiguration festgelegte Anzahl – zum DBMS geöffnet. Diese offenen Verbindungen werden dann EJBs zur Verfügung gestellt, die sie anfordern, um eine Operation mit dem DBMS durchzuführen. Sobald die Operation abgeschlossen ist, gibt das EJB die Verbindung an den Pool zurück. Die Verbindung wird nie geschlossen; sie wird von den verschiedenen Threads gemeinsam genutzt, die auf das DBMS zugreifen
- in [7] geben Sie dem Pool einen Namen
- in [8] ist die Klasse, die die Datenquelle modelliert, die Klasse [javax.sql.DataSource]
- in [9] ist das DBMS, das die Datenquelle enthält, hier MySQL.
- in [10], fahren Sie mit dem nächsten Schritt fort
![]() |
- In [11] stellt das Attribut „Connection Validation Required“ sicher, dass der Pool vor der Gewährung einer Verbindung überprüft, ob diese funktionsfähig ist. Ist dies nicht der Fall, wird eine neue Verbindung erstellt. Dadurch kann eine Anwendung nach einem vorübergehenden Ausfall des DBMS weiterarbeiten. Während des Ausfalls sind keine Verbindungen nutzbar, und es werden Ausnahmen an den Client ausgelöst. Wenn der Ausfall beendet ist, erhalten Clients, die weiterhin Verbindungen anfordern, diese wieder: Dank des Attributs „Connection Validation Required“ werden alle Verbindungen im Pool neu erstellt. Ohne dieses Attribut würde der Pool zwar erkennen, dass die ursprünglichen Verbindungen verloren gegangen sind, aber nicht versuchen, neue zu erstellen.
- In [12] wird für Transaktionen die Isolationsstufe „Read Committed“ festgelegt. Diese Stufe stellt sicher, dass eine Transaktion T2 keine Daten lesen kann, die von einer Transaktion T1 geändert wurden, bis diese vollständig abgeschlossen ist.
- In [13] legen wir fest, dass alle Transaktionen die in [12] angegebene Isolationsstufe verwenden müssen
![]() |
- In [14] und [15] geben Sie die URL der Datenbank an, deren Verbindungen vom Pool verwaltet werden
- In [16] ist der Benutzer „root“
- Fügen Sie in [17] eine Eigenschaft hinzu
- Fügen Sie in [18] die Eigenschaft „Password“ mit dem Wert () in [19] hinzu. Auch wenn dies im Screenshot [19] nicht zu sehen ist, geben Sie keine leere Zeichenfolge ein, sondern () (öffnende Klammer, schließende Klammer), um ein leeres Passwort anzugeben. Falls der Root-Benutzer Ihres MySQL-DBMS ein nicht leeres Passwort hat, geben Sie dieses Passwort ein.
- Beenden Sie in [20] den Assistenten zur Erstellung des Verbindungspools für die MySQL-Datenbank [dbrdvmedecins].
![]() |
- In [21] wurde der Pool erstellt. Klicken Sie auf den entsprechenden Link.
- In [22] können Sie über die Schaltfläche [Ping] eine Verbindung zur Datenbank [dbrdvmedecins] herstellen
- In [23] wird, wenn alles gut geht, eine Meldung angezeigt, dass die Verbindung erfolgreich hergestellt wurde
Sobald der Verbindungspool erstellt wurde, können Sie eine JDBC-Ressource erstellen:
![]() |
- Wählen Sie in [1] den Zweig [JDBC-Ressourcen] aus der Server-Objektstruktur aus
- Erstellen Sie in [2] eine neue JDBC-Ressource
- Geben Sie in [3] der JDBC-Ressource einen Namen. Dieser muss mit dem Namen übereinstimmen, der in der Datei [persistence.xml] verwendet wird:
- Geben Sie in [4] den Verbindungspool an, den die neue JDBC-Ressource verwenden soll: den, den Sie gerade erstellt haben
- In [5] schließen wir den Erstellungsassistenten ab
![]() |
- In [6] die neue JDBC-Ressource
Nachdem die JDBC-Ressource nun erstellt wurde, können Sie die JAR-Datei des EJB bereitstellen:
![]() |
- Wählen Sie unter [1] den Zweig [Enterprise Applications] aus
- Klicken Sie in [2] auf die Schaltfläche [Bereitstellen], um anzugeben, dass Sie eine neue Anwendung bereitstellen möchten
- Geben Sie unter [3] an, dass es sich bei der Anwendung um ein EJB-Modul handelt
- Wählen Sie unter [4] die EJB-JAR-Datei [serveur-ejb-dao-jpa-hibernate.jar] aus, die Ihnen für das Labor zur Verfügung gestellt wurde.
- In [5] können Sie den Namen des EJB-Moduls ändern, wenn Sie möchten
- Führen Sie in [6] den Assistenten für die Bereitstellung des EJB-Moduls aus
![]() |
- In [7] wurde das EJB-Modul bereitgestellt. Es kann nun verwendet werden.
4.9. Testen des EJB der [DAO]-Schicht
Nachdem das EJB für die [DAO]-Schicht unserer Anwendung bereitgestellt wurde, können wir es testen. Dazu verwenden wir den folgenden Java-Client:
![]() |
Die Klasse [MainTestsDaoRemote] [1] ist eine JUnit-4-Testklasse. Die Bibliotheken in [2] bestehen aus:
- die [DAO]-Schicht-EJB-JAR-Datei [3] (siehe Abschnitt 4.6.4).
- die für Remote-EJB-Clients erforderlichen GlassFish-Bibliotheken [4].
Die Testklasse sieht wie folgt aus:
- Zeile 13: Beachten Sie die Instanziierung des Remote-EJB-Proxys. Wir verwenden dessen JNDI-Namen „rdvmedecins.dao“.
- Die Testmethoden verwenden die vom EJB bereitgestellten Methoden (siehe Abschnitt 4.6.4).
Wenn alles gut läuft, sollten die Tests erfolgreich sein:
![]() |
Da die EJB der [dao]-Schicht nun betriebsbereit ist, können wir damit fortfahren, sie über einen Webservice öffentlich zugänglich zu machen.
4.10. Der Webservice der [dao]-Schicht
Eine kurze Einführung in das Konzept eines Webdienstes finden Sie in Abschnitt 14, Seite 111 von [ref1].
Kehren wir zur Serverarchitektur unserer Client/Server-Anwendung zurück:
![]() |
Wir konzentrieren uns hier auf den Webdienst der [DAO]-Schicht. Der einzige Zweck dieses Dienstes besteht darin, die EJB-Schnittstelle der [DAO]-Schicht für plattformübergreifende Clients verfügbar zu machen, die mit einem Webdienst kommunizieren können.
Erinnern Sie sich daran, dass es zwei Möglichkeiten gibt, einen Webdienst zu implementieren:
- die Verwendung einer mit @WebService annotierten Klasse, die in einem Web-Container ausgeführt wird
![]() |
- unter Verwendung eines mit @WebService annotierten EJB, das in einem EJB-Container ausgeführt wird
![]() |
Hier verwenden wir die erste Lösung. In der NetBeans-IDE müssen wir ein Enterprise-Projekt mit zwei Modulen erstellen:
- das EJB-Modul, das im EJB-Container ausgeführt wird: das EJB der [DAO]-Schicht.
- das Web-Modul, das im Web-Container ausgeführt wird: der Webdienst, den wir gerade entwickeln.
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“:
![]() |
- Erstellen Sie in [1] ein neues Projekt in der Kategorie „Java Web“ [2] vom Typ „Webanwendung“ [3].
![]() |
- In [4] benennen wir das Projekt und in [5] geben wir den Ordner an, in dem es erstellt werden soll
- In [6] geben wir den Anwendungsserver an, auf dem die Webanwendung ausgeführt werden soll
- In [7] legen Sie den Anwendungskontext fest
- In [8] überprüfen Sie die Projektkonfiguration.
![]() |
- In [9] das generierte Projekt. Der Webdienst, den wir erstellen, wird die EJB aus dem vorherigen Projekt [10] verwenden. Daher muss er auf die .jar-Datei des EJB-Moduls [10] verweisen.
- Fügen Sie in [11] ein NetBeans-Projekt zu den Bibliotheken des Webprojekts hinzu [12]
![]() |
- Wählen Sie unter [13] den Ordner des EJB-Moduls im Dateisystem aus und bestätigen Sie.
![]() |
- In [14] wurde das EJB-Modul zu den Bibliotheken des Webprojekts hinzugefügt.
In [15] implementieren wir den Webdienst mit der folgenden [WsDaoJpa]-Klasse:
- Zeile 4: Die Klasse [WsdaoJpa] implementiert die Schnittstelle [IDao]. Zur Erinnerung: Diese Schnittstelle ist im EJB-Archiv der [dao]-Schicht wie folgt definiert:
- Zeile 3: Die Annotation @WebService macht die Klasse [WsDaoJpa] zu einem Webservice.
- Zeilen 6–7: Die Referenz auf das EJB in der [DAO]-Schicht wird vom Anwendungsserver in das Feld in Zeile 7 injiziert. Beachten Sie, dass immer die lokale Implementierung (in diesem Fall IDaoLocal) injiziert wird. 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 einfach 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] sehen wir den Webdienst WsDaoJpa und in [2] die Methoden, die er für Remote-Clients bereitstellt.
Werfen wir einen Blick auf die Architektur des Webdienstes, der gerade entwickelt wird:
![]() |
Die Komponenten des Webdienstes, den wir bereitstellen werden, sind:
- [1]: das soeben erstellte Webmodul
- [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 wir die beiden Module zu einem NetBeans-„Enterprise“-Projekt zusammenfassen:
![]() |
Erstellen Sie in [1] ein neues Enterprise-Projekt [2, 3].
![]() |
- In [4,5] benennen wir das Projekt und geben das Verzeichnis für die Erstellung an
- In [6] wählen Sie den Anwendungsserver aus, auf dem die Unternehmensanwendung bereitgestellt werden soll
- In [7] kann ein Unternehmensprojekt drei Komponenten umfassen: Webanwendung, EJB-Modul und Client-Anwendung. Hier wird das Projekt ohne Komponenten erstellt. Diese werden später hinzugefügt.
![]() |
- In [8] die neu erstellte Unternehmensanwendung.
![]() |
- In [9] klicken Sie mit der rechten Maustaste auf [Java EE-Module] und fügen ein neues Modul hinzu
- In [10] werden nur die NetBeans-Module angezeigt, die derzeit in der IDE geöffnet sind. Hier wählen wir das Webmodul [web-service-server-1-ejb-dao-jpa-hibernate] und das EJB-Modul [ejb-server-dao-jpa-hibernate] aus, die wir erstellt haben.
- In [11] werden die beiden Module zum Unternehmensprojekt hinzugefügt.
Wir müssen diese Unternehmensanwendung nun auf dem GlassFish-Server bereitstellen. Als Nächstes muss das MySQL-DBMS gestartet werden, damit auf die vom EJB-Modul verwendete JDBC-Datenquelle „jdbc/dbrdvmedecins“ zugegriffen werden kann.
![]() |
- In [1] starten wir den GlassFish-Server
- Wenn das EJB-Modul [ejb-server-dao-jpa-hibernate] bereitgestellt ist, entladen wir es [2]
- Stellen Sie in [3] die Unternehmensanwendung bereit
![]() |
- In [4] ist sie bereitgestellt. Wir können sehen, dass sie beide Module enthält: Web und EJB.
4.10.2. NetBeans-Projekt – Version 2
Wir zeigen nun, wie Sie den Webdienst bereitstellen, wenn Sie nicht über den Quellcode für das EJB-Modul verfügen, sondern nur über dessen .jar-Archiv.
Das neue NetBeans-Projekt für den Webdienst sieht wie folgt aus:
![]() |
Die wichtigsten Elemente des Projekts sind:
- [1]: Der Webdienst wird durch ein NetBeans-Projekt vom Typ [Webanwendung] implementiert.
- [2]: Der Webdienst wird durch die Klasse [WsDaoJpa] implementiert, die wir bereits behandelt haben
- [3]: das EJB-Archiv für die [DAO]-Schicht, das es der Klasse [WsDaoJpa] ermöglicht, auf die Definitionen der verschiedenen Klassen, Schnittstellen und Entitäten in den Schichten [DAO] und [JPA] zuzugreifen.
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 [webservice-ejb-dao-jpa-hibernate]
- 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. Sie müssen daher das EAR-Archiv der Anwendung [ea-rdvmedecins] manuell bereitstellen:
![]() |
- Das Archiv [ea-rdvmedecins.ear] befindet sich im Ordner [dist] [2] auf der Registerkarte [Dateien] in NetBeans.
- In diesem Archiv [3] finden Sie die beiden Komponenten der Unternehmensanwendung:
- das EJB-Archiv [ejb-server-dao-jpa-hibernate]. Dieses Archiv ist vorhanden, da es Teil der Bibliotheken war, auf die der Webdienst verweist.
- das Webdienst-Archiv [webservice-server-ejb-dao-jpa-hibernate].
- Das Archiv [ea-rdvmedecins.ear] wird durch einen einfachen Build [4] der Unternehmensanwendung erstellt.
- In [5] schlägt der Deployment-Vorgang fehl.
Um das Unternehmensanwendungsarchiv [ea-rdvmedecins.ear] bereitzustellen, gehen wir genauso vor wie bei der Bereitstellung des EJB-Archivs [ejb-server-dao-jpa-hibernate.jar] in Abschnitt 4.2. Wir verwenden erneut den Web-Verwaltungsclient des GlassFish-Servers. Bereits beschriebene Schritte werden hier nicht wiederholt.
Zunächst werden wir die in Abschnitt 4.10.1 bereitgestellte Unternehmensanwendung „entladen“:
![]() |
- [1]: Wählen Sie den Zweig [Enterprise Applications] des GlassFish-Servers aus
- Wählen Sie in [2] die zu entladende Unternehmensanwendung aus und entladen Sie sie dann in [3]
- In [4] wurde die Unternehmensanwendung entladen
![]() |
- Wählen Sie in [1] den Zweig [Enterprise-Anwendungen] des GlassFish-Servers aus
- Stellen Sie in [2] eine neue Unternehmensanwendung bereit
- Wählen Sie in [3] den Typ [Enterprise-Anwendung] aus
- Geben Sie in [4] die .ear-Datei für das NetBeans-Projekt [ea-rdvmedecins] an
- Stellen Sie in [5] dieses Archiv bereit
![]() |
- In [6] wurde die Anwendung bereitgestellt
- In [7] erscheint der Webdienst [WsDaoJpa] im Zweig [Web Services] des GlassFish-Servers. Wählen Sie ihn aus.
- In [8] finden Sie verschiedene Details zum Webdienst. Die für einen Client relevanteste Information ist [9]: die URI des Webdienstes.
- In [10] können Sie den Webdienst testen
![]() |
- In [11] wird die Webdienst-URI angezeigt, der der Parameter ?test hinzugefügt wurde. Diese URI zeigt eine Testseite an. Alle vom Webdienst bereitgestellten Methoden (@WebMethod) werden angezeigt und können getestet werden. Hier testen wir die Methode [13], die die Liste der Clients abruft.
![]() |
- In [14] zeigen wir nur einen Ausschnitt der Antwortseite. Wir können jedoch erkennen, dass die Methode getAllClients tatsächlich die Liste der Clients zurückgegeben hat. Der Screenshot zeigt, dass die Antwort im XML-Format gesendet wird.
Ein Webdienst wird vollständig durch eine XML-Datei beschrieben, die als WSDL-Datei bezeichnet wird:
![]() |
- Wählen Sie in [1] im Web-Verwaltungstool des GlassFish-Servers den Webdienst [WsDaoJpa] aus
- Folgen Sie unter [2] dem Link [WSDL anzeigen]
![]() |
- In [3]: die URI der WSDL-Datei. Dies ist eine wichtige Information. Sie wird benötigt, um Clients für diesen Webdienst zu konfigurieren.
- In [4] die XML-Beschreibung des Webdienstes. Wir werden diesen komplexen Inhalt nicht näher erläutern.
4.10.3. JUnit-Tests für den Webdienst
Wir erstellen ein NetBeans-Projekt, um die zuvor mit einem EJB-Client durchgeführten Tests diesmal mit einem Client für den kürzlich bereitgestellten Webdienst auszuführen. Dabei folgen wir einem Verfahren, das dem in Abschnitt 14.2.1, Seite 115 von [ref1] beschriebenen ähnelt.
![]() |
- in [1], ein klassisches Java-Projekt
- In [2] verwendet die Testklasse
- in [3] nutzt der Client das EJB-Archiv, um auf die Definitionen der Schnittstelle der [DAO]-Schicht und der JPA-Entitäten zuzugreifen. Beachten Sie, dass sich dieses Archiv im Unterordner [dist] des EJB-Modulordners befindet.
Um auf den Remote-Webdienst zuzugreifen, müssen Proxy-Klassen generiert werden:
![]() |
In der obigen Abbildung kommuniziert die Schicht [2] [C=Client] mit der Schicht [1] [S=Server]. Um mit der Schicht [S] zu interagieren, muss der Client [C] eine Netzwerkverbindung zur Schicht [S] herstellen und über ein bestimmtes Protokoll mit ihr kommunizieren. Bei den Netzwerkverbindungen handelt es sich um TCP-Verbindungen, und das Transportprotokoll ist HTTP. Die [S]-Schicht, die den Webdienst repräsentiert, wird durch ein Java-Servlet implementiert, das auf dem GlassFish-Server läuft. Dieses Servlet haben wir nicht selbst geschrieben. Seine Generierung wird von GlassFish automatisiert, basierend auf den Annotationen @WebService und @WebMethod in der von uns geschriebenen Klasse [WsDaoJpa]. In ähnlicher Weise werden wir die Generierung der Client-Schicht [C] automatisieren. Die [C]-Schicht wird manchmal als Proxy-Schicht für den Remote-Webdienst bezeichnet, wobei sich der Begriff „Proxy“ auf ein Zwischenelement in einer Softwarekette bezieht. Hier fungiert der C-Proxy als Vermittler zwischen dem Client, den wir gleich schreiben werden, und dem Webdienst, den wir bereitgestellt haben.
Mit NetBeans 6.5 kann der C-Proxy wie folgt generiert werden (für den weiteren Verlauf muss der Webdienst auf dem GlassFish-Server laufen):
![]() |
- Fügen Sie in [1] dem Java-Projekt
- Wählen Sie in [2] den Zweig [Web Services] aus
- Wählen Sie in [3] [Web Service Client] aus
![]() |
- Geben Sie in [4] die URI der WSDL-Datei des Webdienstes ein. Diese URI wurde in Abschnitt 4.10.2 angegeben.
- Lassen Sie in [5] den Standardwert [JAX-WS] stehen. Der andere mögliche Wert ist [JAX-RPC]
- Nach Bestätigung des Assistenten zur Erstellung des Webdienst-Proxys wurde das NetBeans-Projekt um einen Zweig [Webdienst-Referenzen] erweitert [6]. Dieser Zweig zeigt die vom Remote-Webdienst bereitgestellten Methoden an.
![]() |
- Auf der Registerkarte [Dateien] [7] wurde Java-Quellcode hinzugefügt [8]. Er entspricht dem generierten C-Proxy.
- In [9] befindet sich der Code für eine der Klassen. Wir können sehen [10], dass sie in einem Paket [rdvmedecins.ws] abgelegt wurden. Wir werden den Code für diese Klassen nicht näher erläutern, da er wiederum recht komplex ist.
Für den Java-Client, den wir erstellen, fungiert der generierte C-Proxy als Vermittler. Um auf die Methode M des Remote-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 Remote-Aufrufe übersetzt.
Wir müssen noch wissen, wie die M-Methoden des C-Proxys aufgerufen werden. Kehren wir zu unserer JUnit-Testklasse zurück:
![]() |
In [1] ist die Testklasse [MainTestsDaoRemote] dieselbe, die bereits beim Testen des EJB der [dao]-Schicht verwendet wurde:
- Zeile [13], der Test „test1“ bleibt unverändert.
- Zeile [9], der Inhalt der [init]-Methode wurde gelöscht.
Zu diesem Zeitpunkt enthält das Projekt Fehler, da die Testmethode [test1] die Entitäten [Client], [Medecin], [Creneau] und [Rv] verwendet, die sich nicht mehr in denselben Paketen wie zuvor befinden. Sie befinden sich nun im generierten C-Proxy-Paket. Wir entfernen die entsprechenden Import-Anweisungen und generieren sie mithilfe der Operation „Importe korrigieren“ neu.
![]() |
Kehren wir zum Code für die Testklasse [MainTestsDaoRemote] zurück:
Die Methode [init] in Zeile 10 muss die Referenz auf die [dao]-Schicht in Zeile 7 initialisieren. Wir müssen wissen, wie wir den generierten C-Proxy in unserem Code verwenden. NetBeans unterstützt uns bei diesem Vorgang.
![]() |
- Wählen Sie die [getAllClients]-Methode des Webdienstes in [1] mit der Maus aus, ziehen Sie diese Methode dann per Drag & Drop in die [init]-Methode der Testklasse.
Das Ergebnis ist [2]. Dieses Code-Gerüst zeigt uns, wie der generierte C-Proxy verwendet wird:
- Zeile [5] zeigt, dass die Methode [getAllClients] eine Methode des in Zeile 3 definierten Objekts [WsDaoJpa] ist. Der Typ [WsDaoJpa] ist eine Schnittstelle, die dieselben Methoden bereitstellt wie der Remote-Webdienst.
- In Zeile [3] wird das [WsDaoJpaPort]-Objekt von einem anderen Objekt vom Typ [WsDaoJpaService] abgerufen, das in Zeile 2 definiert ist. Der Typ [WsDaoJpaService] repräsentiert den lokal generierten C-Proxy.
- Da der Zugriff auf den Remote-Webdienst fehlschlagen kann, ist der gesamte Codeblock in einen try/catch-Block eingeschlossen.
- Die C-Proxy-Objekte befinden sich im Paket [rdvmedecins.ws]
Sobald dieser Code verstanden ist, sehen wir, dass die lokale Referenz auf den Remote-Webdienst mit dem folgenden Code abgerufen werden kann:
Der Code für die JUnit-Testklasse sieht dann wie folgt aus:
Wir sind nun bereit für den Test:
![]() |
In [1] wird der JUnit-Test ausgeführt. In [2] wird er bestanden. Wenn wir uns die Ausgabe in der NetBeans-Konsole ansehen, sehen wir 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 toString-Methode, die die verschiedenen Felder eines [Client]-Objekts 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 toString-Methode in der [Client]-Entität des C-Proxys nicht generiert. Dies erklärt die vorherige Anzeige. Dies beeinträchtigt den JUnit-Test nicht: Er wurde bestanden. Wir gehen nun davon aus, dass wir über einen funktionsfähigen Webdienst verfügen.






























































































