Inhaltsverzeichnis

Endlich wieder Programmieren. đŸ’» An dieser Stelle kehren wir noch einmal zu letztem Semester zurĂŒck und vertiefen die Entwicklung serverseitiger Webanwendungen mit der Jakarta Enterprise Edition.

Lernziele dieser Einheit

Nach Abschluss dieser Einheit kannst du 


Âč FrĂŒher hieß das Projekt „Java Enterprise Edition” und wurde von Oracle vorangetrieben. Seit der Übergabe an die Eclipse Foundation im Jahr 2018 wurde es in „Jakarta Enterprise Edition” umbenannt.

🏁

Jakarta EE im Überblick

Bildnachweis: Pixabay: rawpixel

Was ist die Jakarta Enterprise Edition?

Grober Aufbau eines Java-Applikationsservers

Die Jakarta Enterprise Edition ist ein offener Standard fĂŒr javabasierte Anwendungsserver. Diese werden von unterschiedlichen Herstellern angeboten:

Jeder Anwendungsserver besitzt dabei einen Webcontainer zur Bereitstellung von Webinhalten sowie eine EJB-Container zur AusfĂŒhrung der fachlichen Anwendungsklassen. DarĂŒber hinaus bietet er viele eingebaute Zusatzfunktionen:

Aufbau eines Applikationsservers

Interne Bestandteile eines Java-Applikationsservers

Webprogrammierung

Servlets

Grundlegende Klassenbibliothek zur Reaktion auf HTTP-Anfragen. Es handelt sich dabei um die Basistechnologie, die allen höheren Webframeworks fĂŒr Jakarta EE zugrunde liegt.

Java Server Pages

Serverseitige Erweiterung von HTML. Erlaubt es, den HTML-Code dynamisch auf dem Server zu erzeugen, bevor er an den Browser geschickt wird.

Java Server Faces

Von Oracle entwickeltes, mit Jakarta EE ausgeliefertes Webframework. Nutzt eine an HTML angelehnte Beschreibungssprache zur Definition des Layouts.

Anwendungslogik

Enterprise Java Beans

Spezielle Laufzeitumgebung fĂŒr die fachlichen Klassen einer Anwendung. Sie ermöglichen es, Services zu definieren, die von lokalen und entfernten Clients genutzt werden können.

Java Database Connection

Allgemeine Klassenbibliothek fĂŒr den Zugriff auf SQL-Datenbanken. Sie bildet die Grundlage fĂŒr JPA und JTA und wird heutzutage selten direkt genutzt.

Java Persistence API

O/R-Mapper zur Vereinfachung des Datenbankzugriffes. Die Felder einer Tabelle werden automatisch auf die Attribute einer Java-Bean gemappt.

Java Transaction API

Framework fĂŒr von der Datenbank unabhĂ€ngige, verteilte Transaktionen.

Schnittstellen

Java API for XML-Webservices

Klassenbibliothek zum Erstellen und Aufrufen von SOAP-Webservices.

Java API for REST-Webservices

Klassenbibliothek zum Erstellen und Aufrufen von REST-Webservices.

Java Message Services

Klassenbibliothek fĂŒr den Zugriff auf einen Message Broker.

Java Mail API

Hilfsklassen zum Versenden von E-Mails.

Sonstiges

Java Authentication & Authorization Service

Rollenbasierte Benutzer- und Berechtigungsverwaltung. Erlaubt es, die Benutzer entweder in einer Datenbanktabelle abzulegen oder auf externe Provider, wie zum Beispiel LDAP-Verzeichnisse, zuzugreifen.

Fallbeispiele fĂŒr Java auf dem Server

Im Unternehmensumfeld geht es hĂ€ufig darum, mit unterschiedlichen EndgerĂ€ten eine gemeinsame Datenbasis zur Dokumentation aller GeschĂ€ftsvorgĂ€nge zu pflegen. Anwendungen wie diese besitzen daher ein ausgefeiltes Datenmodell und darauf aufbauend sehr viele Services, welche die GeschĂ€ftsprozesse des Unternehmens abbilden. Das Datenmodell wird dabei durch die Persistence Entity-Klassen modelliert, wĂ€hrend die Services in Enterprise Java Beans enthalten sind. Fremde Clientprogramme können die EJBs ĂŒber Rechnergrenzen hinweg direkt aufrufen. Innerhalb des Applikationsservers stehen sie aber auch zur Nutzung in Webanwendungen zur VerfĂŒgung.

Architekturskizze einer Point-Of-Sale-Anwendung

Bildnachweise: Wikipedia: Tokaito, Pixabay: Snap_it, Pixabay: Nick_H, Pixabay: Clker-Free-Vector-Images, Pixabay: Samuel1983

Dieses Beispiel zeigt ein großes Webportal mit mehreren, von der restlichen Anwendungslogik entkoppelten Webfrontends. Zur besseren Skalierung werden getrennte Server fĂŒr die Webfrontends (sog. „Webcontainer"Âč) und das Backend genutzt. Im Backend werden zusĂ€tzlich die Dienste fremder Anbieter per Webservice integriert.

Âč Vollwertige Jakarta EE-Applikationsserver bestehen im Grunde genommen aus nichts anderem als einem Webcontainer und einem EJB-Container, wobei der Webcontainer die Servlet- und webbezogenen APIs zur VerfĂŒgung stellt und der EJB-Container den Rest. Wenn man aber weiß, dass man die Funktionen des EJB-Containers nicht benötigt, kann man den Webcontainer auch separat installieren.

Architekturskizze eines großen Reiseportals

Bildnachweise: Pixabay: www_slon_pics, Pixabay: Julius_Silver, Pixabay: TheDigitalArtist, Pixabay: Didgeman, Pixabay: joe137, Pixabay: Olichel

Aufgabe 1: Ein kleines Java-EE-Quiz

Aufgabe 1.1: Die Jakarta Enterprise Edition

a) Um was fĂŒr eine Middleware handelt es sich bei der Jakarta Enterprise Edition?

  1. Kommunikationsorientierte Middleware
  2. Anwendungsorientierte Middleware

b) Wo gibt es die Jakarta Enterprise Edition zum herunterladen?

  1. Bei Oracle, dem Entwickler von Java
  2. Bei Microsoft, allerdings nur fĂŒr Windows
  3. Bei den Herstellern der Applikationsserver
  4. Bei der Eclipse Foundation
  5. Gar nicht, sie ist in der Sprache Java enthalten

c) Welche der folgenden Schnittstellen bietet ein typischer Anwendungsserver?

  1. Entfernte Methodenaufrufe
  2. SOAP-Webservices
  3. REST-Webservices
  4. Nachrichten ĂŒber einen Message Broker
  5. HTTP zum Aufruf von Webanwendungen

Aufgabe 1.2: Komponentenbasierte Entwicklung

a) Welche Eigenschaften besitzt eine Klasse, wenn sie eine Softwarekomponente ist?

  1. Alle Methoden und Attribute sind public.
  2. Sie kapselt eine in sich geschlossene FunktionalitÀt.
  3. Sie hÀngt nur lose von anderen Komponentenklassen ab.
  4. Sie implementiert das Interface WebComponent.
  5. Idealerweise kann sie in mehreren Anwendungen genutzt werden.
  6. Sie besitzt einen parameterlosen Konstruktor.
  7. Sie kann hÀufig gegen eine alternative Implementierung getauscht werden.

b) Was schĂ€tzt du, was fĂŒr eine austauschbare Softwarekomponente zutreffen muss?

  1. Sie besitzt ein Interface, das ihre fachlichen Methoden definiert.
  2. Die Klasse darf nicht von einer anderen Klasse erben.
  3. Die Klasse muss so geschrieben sein, dass mehrere Implementierungen zulÀssig sind.
  4. Die Verwender der Klasse mĂŒssen gegen ein Interface und nicht gegen die Klasse programmiert werden.
  5. Die Softwarekomponente sollte auf einem eigenen Applikationsserver deployed werden.
  6. Die Klasse sollte eine bestimmte UI-Technologie auf Seiten der Clients vorschreiben.

Lösung: Aufgabe 1.1: 2, 3, alle; Aufgabe 1.2: 2 + 3 + 5 + 7, 1 + 3 + 4

MVC-Webanwendungen mit Java

Bildnachweis: Pixabay: rawpixel

Welche Aufgaben ĂŒbernimmt der Server?

  • Der Klassiker: Die Anwendungslogik liegt komplett auf dem Server.
  • JavaScript kommt im Browser wenn ĂŒberhaupt nur sehr sparsam zum Einsatz.
  • Stattdessen fĂŒhrt jede Aktion dazu, dass eine neue Seite vom Server geladen wird.
  • Der Server fĂŒhrt dabei die Anwendungslogik aus und generiert das anzuzeigende HTML.

Das schauen wir uns heute etwas genauer an.

  • Das Beste beider Welten: Browser und Server beinhalten je einen Teil der Anwendungslogik.
  • Der initiale HTML-Code kann vom Server generiert werden oder in einer einfachen HTML-Datei liegen.
  • Bei verschiedenen Aktionen werden mit JavaScript weitere Daten mit dem Server ausgetauscht.
  • Die empfangenen Daten werden dabei durch geschickte DOM-Manipulation sichtbar gemacht.

Dieses Modell behandeln im Kapitel ĂŒber REST-Webservices.

Alle guten Dinge sind drei: Model, View & Controller

Model

  • Enterprise Java Beans
  • Persistence Entities

Kapseln die fachliche Logik und das Datenmodell.

View

  • HTML, CSS, JS-Dateien
  • Java Server Pages

Übernehmen die Darstellung auf dem Bildschirm.

Controller

  • Servlets

Reagieren auf HTTP-Anfragen und vermitteln zwischen Model und View.

Beispiel: MVC mit Servlets und JSP

So sieht das Netbeans-Projekt aus. Wir bauen ein kleines GĂ€stebuch.

Diese Persistence Entity entspricht einem Eintrag in der Datenbank.

package dhbwka.wwi.vertsys.javee.guestbook; import java.io.Serializable; import java.sql.Date; import java.sql.Time; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; /** * Persistenzklasse fĂŒr einen GĂ€stebucheintrag. */ @Entity public class GuestbookEntry implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name = ""; private Date visitDate = new Date(System.currentTimeMillis()); private Time visitTime = new Time(System.currentTimeMillis()); public GuestbookEntry() { } public GuestbookEntry(String name) { this.name = name; } //<editor-fold defaultstate="collapsed" desc="Setter und Getter"> public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getVisitDate() { return visitDate; } public void setVisitDate(Date visitDate) { this.visitDate = visitDate; } public Time getVisitTime() { return visitTime; } public void setVisitTime(Time visitTime) { this.visitTime = visitTime; } //</editor-fold> }

Dies ist eine Enterprise Java Bean. Sie enthÀlt die Methoden zum Lesen und Schreiben der EintrÀge.

package dhbwka.wwi.vertsys.javee.guestbook; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; /** * Enterprise Java Bean zum Auslesen und Speichern von GÀstebucheintrÀgen. */ @Stateless public class GuestbookBean { @PersistenceContext EntityManager em; /** * @return Liste mit allen GÀstebucheintrÀgen */ public List<GuestbookEntry> findAllEntries() { return em.createQuery("SELECT e FROM GuestbookEntry e " + " ORDER BY e.visitDate DESC, " + " e.visitTime DESC") .getResultList(); } /** * Speichert einen neuen GÀstebucheintrag. * @param name Name des Besuchers * @return Der gespeicherte Eintrag */ public GuestbookEntry createNewEntry(String name) { GuestbookEntry entry = new GuestbookEntry(name); em.persist(entry); return em.merge(entry); } }

Dies ist das Servlet, das bei jeder GET- und POST-Anfrage durchlaufen wird.

package dhbwka.wwi.vertsys.javee.guestbook; import java.io.IOException; import java.util.List; import javax.ejb.EJB; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet fĂŒr die GĂ€stebuchseite */ @WebServlet(urlPatterns = {"/index.html"}) public class GuestbookServlet extends HttpServlet { @EJB GuestbookBean guestbookBean; @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Alle vorhandenen EintrĂ€ge aus der Datenbank lesen und im Request // Context ablegen, damit sie in der JSP zur VerfĂŒgung stehen List<GuestbookEntry> entries = this.guestbookBean.findAllEntries(); request.setAttribute("entries", entries); // Anfrage an die JSP weiterleiten request.getRequestDispatcher("guestbook.jsp").forward(request, response); // In der Session liegende Fehlermeldung verwerfen, damit wir beim // nĂ€chsten Aufruf wieder mit einem leeren Eingabefeld anfangen HttpSession session = request.getSession(); session.removeAttribute("fehler"); session.removeAttribute("name"); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // PrĂŒfen, ob der Anwender seinen Namen eingegeben hat HttpSession session = request.getSession(); String fehler = ""; String name = request.getParameter("name"); if (name == null || name.trim().isEmpty()) { fehler = "Bitte gib erst deinen Namen ein."; session.setAttribute("fehler", fehler); session.setAttribute("name", name); } // Neuen Eintrag speichern if (fehler.isEmpty()) { this.guestbookBean.createNewEntry(name); } // Browser auffordern, die Seite neuzuladen response.sendRedirect(request.getContextPath()); } }

Hier die Datei WEB-INF/guestbook.jsp mit dem JSP-Code zur Anzeige der Seite.

<%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>GĂ€stebuch MVC-Beispiel</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <h1>Mein kleines GĂ€stebuch</h1> <form method="POST"> <input type="text" name="name" placeholder="Dein Name" value="${name}"/> <button type="submit">Abschicken</button> </form> <c:if test="${!empty fehler}"> <p class="error"> ${fehler} </p> </c:if> <ul> <c:forEach items="${entries}" var="entry"> <li> ${entry.visitDate}, ${entry.visitTime}: ${entry.name} </li> </c:forEach> </ul> </div> </body> </html>

Damit es ordentlich aussieht, nutzen wir ein kleines Stylesheet namens style.css.

html, body { font-family: sans-serif; font-size: 12pt; height: 100%; margin: 0; padding: 0; } html { background-image: url(https://picsum.photos/1024/?image=871); background-repeat: no-repeat; background-position: center center; background-size: cover; } body { display: flex; justify-content: center; align-items: center; } .container { background: rgba(255,255,255,0.8); border-radius: 0.5em; padding: 1em; margin: 2em; } h1, h2 { color: crimson; text-shadow: 0 0 1px rgba(0,0,0,0.5); margin: 0 0 0.5em 0; } h2 { color: deepskyblue; } input[type="text"] { display: block; width: 25em; box-sizing: border-box; border: 1px solid grey; margin-bottom: 0.5em; } ul { list-style: none; margin: 1em 0 0 0; padding: 0; font-size: 90%; } li { margin: 0 0 0.75em 0; padding: 0; } .error { color: red; font-weight: bold; margin: 0 0 0.75em 0; }

Und so sieht die fertige Anwendung aus:

Wo geht's denn hier zur IDE?

Bildnachweis fĂŒr das Endesymbol: Pixabay: janf93

Aufgabe 2: Deine erste Enterprise Java Bean

Lege in Netbeans ein Maven Java-Webprojekt an und probiere folgende Sachen aus:

  1. Lösche die Datei index.html aus dem Ordner Web Pages.
  2. Stattdessen kopiere die Dateien guestbook.jsp und style.css in das Projekt.
  3. Lege die Klassen GuestbookEntry, GuestbookBean und GuestbookSerlvet wie gezeigt an.
  4. Lege die beiden Konfigurationsdateien persistence.xml und orm.xml wie gezeigt an.
  5. Starte die Anwendung und schaue, ob alles fehlerfrei funktioniert.

Aufgabe 3: Ein kleines MVC-Quiz

Aufgabe 3.1: Allgemeine Fragen

a) Welche ArchitekturansĂ€tze kommen fĂŒr serverseitige Webanwendungen in Frage?

  1. Alle Logik auf dem Server belassen und auch das HTML auf dem Server generieren.
  2. Das HTML im Browser generieren, jedoch die fachlichen Funktionen auf dem Server lassen.
  3. Das HTML im Browser generieren und auch die fachlichen Funktionen im Browser ausfĂŒhren.
  4. Einen Native Client fĂŒr unterschiedliche Betriebssysteme mit dem Server als Backend entwickeln.

b) WofĂŒr steht die AbkĂŒrzung MVC?

  1. Model-View-Component
  2. Make-Visual-Controllers
  3. Many-Versatile-Classes
  4. Model-View-Controller
  5. Jeden Morgen viel Chaos

c) Welche Aufgaben ĂŒbernimmt der Controller bei MVC?

  1. Er beinhaltet die fachliche Anwendungslogik.
  2. Er beinhaltet das Datenmodell der Anwendung.
  3. Er vermittelt zwischen Model und View.
  4. Er reagiert auf entfernte Methodenaufrufe.

d) Welche Aufgaben ĂŒbernimmt das Model bei MVC?

  1. Es ist schön anzusehen. 👒
  2. Es beinhaltet die fachliche Anwendungslogik.
  3. Es beinhaltet das Datenmodell der Anwendung.
  4. Es vermittelt zwischen View und Controller.
  5. Es reagiert auf Webservice-Aufrufe.

Aufgabe 3.2: MVC-Webanwendungen mit Java

a) Welcher Teil einer Webanwendung entspricht dem Model?

  1. Die Servlets
  2. Die Java Server Pages und HTML-Seiten
  3. Die Enterprise Java Beans
  4. Die Persistence Entities
  5. Die sonstigen Klassen der Anwendung

b) Welcher Teil einer Webanwendung entspricht dem Controller?

  1. Die Servlets
  2. Die Java Server Pages und HTML-Seiten
  3. Die Enterprise Java Beans
  4. Die Persistence Entities
  5. Die sonstigen Klassen der Anwendung

c) Welche Annotation kennzeichnet eine Persistence Entity?

  1. @PersistenceUnit
  2. @EntityManager
  3. @DatabaseTable
  4. @Entity
  5. @ORMappedBean

d) Welche Annotation kennzeichnet eine Stateless Session Bean?

  1. @Stateless
  2. @Bean
  3. @SessionBean
  4. @EJB
  5. @ModelBean

e) Mit welcher Annotation erhÀlt man eine Referenz auf eine Enterprise Java Bean?

  1. @Object
  2. @Reference
  3. @Inject
  4. @Bean
  5. @EJB

Lösung: Aufgabe 3.1: 1 + 2, 4, 3, 2 + 3; Aufgabe 3.2: 3 + 4, 1, 4, 1, 5

Enterprise Java Beans im Detail

Bildnachweis: Pixabay: rawpixel

Mehr als nur Stateless Session Beans

Singleton Session Beans

☕ Eine Instanz fĂŒr alle Clients
☕ Threadsicherheit beachten!
@Singleton public class CityBean { // 
 }

Stateless Session Beans

☕ Geteilte Instanzen fĂŒr alle Clients
☕ Meistens die beste Wahl
@Stateless public class CountryBean { // 
 }

Stateful Session Beans

☕ Jedem Kind sein Luftballon 🎈
☕ Verbraucht viele Ressourcen
@Stateful public class RiverBean { // 
 }

Doch Vorsicht! Der Client einer Bean ist immer nur ihr direkter Verwender. Gerade bei Stateful Session Beans macht das einen Unterschied, wie die folgende Abbildung zeigt. @Stateful alleine reicht nicht aus, um eine Bean einem einzelnen Besucher einer Webseite zuzuordnen. HierfĂŒr muss die Bean manuell erzeugt und in der Session abgelegt werden.

Verschiedene Aufrufketten fĂŒr EJBs

Nur fĂŒr Zuhause: EJBs mit No-Interface View

So haben unsere Enterprise Java Beans bisher ausgesehen:

@Stateless public class ArticleInformationBean { public Article findArticle(long id) { 
 } public List<Article> searchArticles(String search) { 
 } 
 }
🔰 Sie besitzen kein Interface und erben von keiner Klasse.
🔰 Sie sind deshalb nicht wirklich austauschbar.
🔰 Sie können nicht ĂŒber Rechnergrenzen hinweg aufgerufen werden.
🔰 Auch nicht aus anderen Webanwendungen desselben Servers heraus.
🔰 Sie existieren lediglich innerhalb der eigenen Webanwendung.
â˜ș Und das ist völlig okay so!

Wann braucht man ein Business Interface?

🐩 Soll eine EJB austauschbar sein, mĂŒssen ihre Methoden in einem Business Interface deklariert werden.
🐩 Das Interface kann dabei ein Local Interface oder ein Remote Interface sein.
🐩 Die Verwender der Bean dĂŒrfen sich dann nur auf das Interface und niemals auf die Klasse beziehen.

Ein Local Interface definiert Methoden, die innerhalb derselben JVM aufrufbar sind. Der Aufrufer kann dabei auch Teil einer anderen Anwendung sein, solange sie im selben Server in derselben JVM lÀuft.

/** * Deklaration der verfĂŒgbaren Business Methoden als Local Interface */ @Local public interface Payment { List<String> getSupportedPaymentMethods(); PaymentResult payDueAmount(String method, double amount); } /** * Erste Version unseres Bezahldienstes */ @Stateless public class PaymentBeanV1 implements Payment { List<String> getSupportedPaymentMethods() { 
 } PaymentResult payDueAmount(String method, double amount) { 
 } } /** * Verwendung des Dienstes innerhalb einer anderen EJB */ @Stateless public class ShoppingCartBean { // Hier nur das Interface angeben! @EJB Payment payment; 
 }

Ein Remote Interface definiert Methoden, die auch ĂŒber JVM- und Rechnergrenzen hinweg aufrufbar sind. Dies wird heutzutage zugunsten von Webservices aber nur noch selten gemacht.

/** * Deklaration der entfernt aufrufbaren Business Methoden als Remote Interface */ @Remote public interface MovieSearch { List<Movie> searchMovies(String search); } /** * Implementierende Enterprise Java Bean */ @Stateless public class MovieSearchBean implements MovieSearch { List<Movie> searchMovies(String search) { 
 } } /** * Verwendung der Bean in einem Servlet */ @WebServlet(urlPatterns={"/search/"}) public class MovieSearchServlet extends HttpServlet { // Hier nur das Interface angeben @EJB MovieSearch search; 
 }

Gibt es mehrere Implementierungen zum selben Interface, mĂŒssen diese ĂŒber einen zusĂ€tzlichen Namen auseinander gehalten werden. Der Name muss innerhalb der gesamten Anwendung eindeutig sein und darf nur fĂŒr eine EJB-Klasse verwendet werden.

/** * Ein einfaches Business Interface */ @Local public interface ReadProductData { public Map<String, String> getProductData(long articleId); } /** * Besondere Implementierung fĂŒr Administratoren */ @Stateless(name="ReadProductData-Admin") public class ReadProductDataAdminBean implements ReadProductData { public Map<String, String> getProductData(long articleId) { 
 } } /** * Einfache Version fĂŒr normale Anwender */ @Stateless(name="ReadProductData-SimpleUser") public class ReadProductDataSimpleUserBean implements ReadProductData { public Map<String, String> getProductData(long articleId) { 
 } } /** * Verwendung der Version fĂŒr Administratoren */ @WebServlet(urlPatterns={"/admin/product/*"}) public class UserProfileAdminServlet extends HttpServlet { // Interface plus der richtige Name @EJB(beanName="ReadProductData-Admin") ReadProductData readProductData; 
 }

Woher kommen eigentlich die EJB-Objekte?

Woher kommen die EJB-Objekte!?
Die Variablen mĂŒssten doch leer sein.
Ist es Zauberei?

NatĂŒrlich ist es keine Zauberei. đŸ‘» Das Prinzip, dass alle mit @EJB ausgezeichneten Variablen automatisch mit Inhalten versorgt werden, nennt sich Dependency Injection. Es handelt sich dabei um eine Anwendung von Inversion of Control bzw. dem Hollywood-Prinzip. Um zu verstehen, was hier passiert, musst du den Lebenszyklus von Enterprise Java Beans kennen:

@Stateful public class GenieTheGhostBean { @EJB MagicLampBean lamp; public GenieTheGhostBean { // Konstruktor: Hier ist this.lamp noch null! } @PostConstruct public void onInit() { // Ersatz fĂŒr den Konstruktor: Hier ist this.lamp gefĂŒllt! } @PreDestroy public void onDestroy() { // Die Bean wird gleich verworfen } public void placeFirstWish(String wish) { // Normale Business Methode } public void placeSecondWish(String wish) { // Normale Business Methode } @Remove public void placeThirdWish(String wish) { // Nachdem der Client diese Methode aufgerufen hat, verschwindet die Bean. // @Remove ist daher nur in Stateful Session Beans erlaubt. } @Remove public void leaveMeAlone() { // Bewirkt ebenfalls, dass die Bean verschwindet. } }

Aufgabe 4: Ein kleines EJB-Quiz

Aufgabe 4.1: Die verschiedenen Beantypen

a) Welche der folgenden Annotationen zeichnet eine Klasse nicht als EJB aus?

  1. @Stateless
  2. @Stateful
  3. @Singleton
  4. @EJB
  5. @MessageDriven

b) Welche Aussage trifft am ehesten auf Stateless Session Beans zu?

  1. Der Server verwaltet einen Pool von Instanzen, die zwischen allen Clients geteilt werden.
  2. Jeder Client greift immer auf dieselbe Objektinstanz zu.
  3. Der Server hÀlt nur eine Instanz vor, die sich alle Clients teilen.

c) Und welche Aussage trifft am ehesten auf Stateful Session Beans zu?

  1. Der Server verwaltet einen Pool von Instanzen, die zwischen allen Clients geteilt werden.
  2. Jeder Client greift immer auf dieselbe Objektinstanz zu.
  3. Der Server hÀlt nur eine Instanz vor, die sich alle Clients teilen.

d) Was passiert, wenn ein Servlet mit @EJB auf eine Stateful Session Bean zugrefit?

  1. Jeder Aufrufer des Servlets bekommt seine eigene EJB-Instanz zugewiesen.
  2. Bei den meisten Servern arbeiten alle Aufrufer mit derselben EJB-Instanz.
  3. Die EJB-Instanz wird bei jedem Aufruf des Servlets neu erzeugt.

Aufgabe 4.2: Business Interfaces fĂŒr EJBs

a) Eine EJB benötigt immer ein Business Interface.

  1. Wahr
  2. Falsch

b) Welche Annotation kennzeichnet ein Local Interface?

  1. @EJB
  2. @LocalInterface
  3. @Local
  4. @Interface

c) Und welche Annotation kennzeichnet ein Remote Interface?

  1. @EJB
  2. @Remote
  3. @Interface
  4. @RemoteInterface

d) Was ist zu tun, wenn mehrere EJB-Klassen dasselbe Business Interface implementieren?

  1. Die Klassen sind ĂŒber die @EJB-Annotation mit eindeutigen Namen zu versehen.
  2. Nichts, Java erkannt am Klassennamen, welches Objekt gemeint ist.
  3. Nichts, dieser Fall ist nicht erlaubt.

Aufgabe 4.3: Der EJB-Lebenszyklus

a) Ab welchem Zeitpunkt sind die mit @EJB gekennzeichneten Variablen gefĂŒllt?

  1. Schon bevor der Konstruktor lÀuft
  2. Bereit wÀhrend der Konstruktor lÀuft
  3. SpÀtestens wenn die @PostConstruct-Methode lÀuft
  4. Sobald die erste Business Methode aufgerufen wird

b) Was bewirkt eine mit @PreDestroy ausgezeichnete Methode?

  1. Sie sorgt dafĂŒr, dass die EJB verschwindet, sobald ein Client sie aufruft.
  2. Sie kann fĂŒr AufrĂ€umarbeiten genutzt werden, bevor eine EJB-Instanz verschwindet.
  3. Sie sorgt dafĂŒr, dass die komplette Anwendung beendet wird.
  4. Sie muss aufgerufen werden, bevor die @Destroy-Methode gerufen wird.

b) Und was bewirkt eine mit @Remove ausgezeichnete Methode?

  1. Sie sorgt dafĂŒr, dass die EJB verschwindet, sobald ein Client sie aufruft.
  2. Sie kann fĂŒr AufrĂ€umarbeiten genutzt werden, bevor eine EJB-Instanz verschwindet.
  3. Sie sorgt dafĂŒr, dass die komplette Anwendung beendet wird.
  4. Sie muss aufgerufen werden, bevor die @PostRemove-Methode gerufen wird.

c) Welche Beantypen dĂŒrfen eine @Remove-Methode besitzen?

  1. Alle Enterprise Java Beans
  2. Nur Stateless Session Beans
  3. Nur Stateful Session Beans
  4. Nur Message Driven Beans
  5. Stateless und Stateful Session Beans

d) Eine EJB darf mehr wie eine @Remove-Methode besitzen.

  1. Wahr
  2. Falsch

Lösung: Aufgabe 4.1: 4, 1, 2, 2; Aufgabe 4.2: 2, 3, 2, 1; Aufgabe 4.3: 3, 2, 1, 3, 1

Hinweise zum Schluss

Bildnachweis: Pixabay: rawpixel

Do & Don't

Auswahl des richtigen Architekturansatzes

Strukturierung des Quellcodes

Implementierung der Enterprise Java Beans

Sonstige Tipps

Rechtshinweise

Creative Commons Namensnennung 4.0 International

§