3. Grundlagen der Webentwicklung in Java
Wir befassen uns nun mit der Entwicklung dynamischer Webanwendungen, c.a.d, bei denen die an den Benutzer gesendeten Seiten, HTML, von Programmen generiert werden.
3.1. Erstellen eines Webprojekts in Eclipse
Wir werden eine erste Webanwendung mit Eclipse/Tomcat entwickeln. Dabei gehen wir ähnlich vor wie bei der Erstellung einer Webanwendung ohne Eclipse. Nach dem Start von Eclipse erstellen wir ein neues Projekt:

das wir als dynamisches Webprojekt definieren:

Auf der ersten Seite des Assistenten geben wir den Namen des Projekts „[1]“ und dessen Speicherort „[2]“ an:

Auf der zweiten Seite des Assistenten übernehmen wir die Standardwerte:

Auf der letzten Seite des Assistenten werden wir aufgefordert, den Anwendungskontext [3] festzulegen:

Sobald der Assistent bestätigt wurde, stellt Eclipse eine Verbindung zur Website her, um bestimmte Dokumente abzurufen, die es zwischenspeichern möchte, um unnötige Netzwerkzugriffe zu vermeiden. Anschließend wird eine Lizenzanfrage gestellt:

Wir bestätigen dies. Eclipse erstellt das Webprojekt. Um es anzuzeigen, verwendet es eine Umgebung, die als „Perspektive“ bezeichnet wird und sich von derjenigen unterscheidet, die für ein klassisches Java-Projekt verwendet wird:

Die mit einem Webprojekt verbundene Perspektive ist die Perspektive J2EE. Wir bestätigen sie, um zu sehen, was passiert... Das Ergebnis sieht wie folgt aus:

Die Perspektive J2EE ist für einfache Webprojekte eigentlich unnötig komplex. In diesem Fall reicht die Java-Perspektive aus. Um diese zu erhalten, verwenden wir die Option [Window -> Open perspective -> Java]:

src: Enthält den Java-Code der Klassen der Anwendung sowie die Dateien, die im Verzeichnis Classpath der Anwendung enthalten sein müssen.
build/classes (nicht dargestellt): Enthält die .class-Dateien der kompilierten Klassen sowie eine Kopie aller Dateien außer den .java-Dateien, die sich in src befinden. Eine Webanwendung verwendet häufig sogenannte „Ressourcendateien“, die sich im Classpath der Anwendung, dem c.a.d, befinden müssen. Alle Ordner, die von der JVM durchsucht werden, wenn die Anwendung auf eine Klasse verweist, sei es während der Kompilierung oder zur Laufzeit. Eclipse sorgt dafür, dass der Ordner „build/classes“ Teil des Web-Verzeichnisses ist. Die „Ressourcendateien“ werden im Ordner „src“ abgelegt, wobei Eclipse sie automatisch in „build/classes“ kopiert.
WebContent: Enthält die Ressourcen der Webanwendung, die nicht im Verzeichnis Classpath der Anwendung enthalten sein müssen.
WEB-INF/lib: Enthält die .jar-Dateien, die die Webanwendung benötigt.
Sehen wir uns den Inhalt der Datei [WEB-INF/web.xml] an, die die Anwendung [personne] konfiguriert:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name> personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Auf diese Art der Konfiguration sind wir bereits gestoßen, als wir in Abschnitt 2.3.4 die Erstellung von Startseiten behandelt haben. Diese Datei dient lediglich dazu, eine Reihe von Startseiten zu definieren. Wir behalten nur die erste bei. Die Datei [web.xml] sieht nun wie folgt aus:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Der Inhalt der oben genannten Datei XML muss den Syntaxregeln entsprechen, die in der Datei definiert sind, auf die das Attribut [xsi:schemaLocation] des öffnenden Tags <web-app> verweist. Diese Datei ist hier [http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd]. Es handelt sich um eine Datei namens XML, die direkt mit einem Browser aufgerufen werden kann. Ist dieser Browser aktuell genug, kann er eine Datei namens XML anzeigen:

Eclipse versucht, die Gültigkeit des Dokuments XML anhand der im Attribut [xsi:schemaLocation] des öffnenden Tags <web-app> angegebenen .xsd-Datei zu überprüfen. Dazu stellt es eine Netzwerkverbindung her. Befindet sich Ihr Computer in einem privaten Netzwerk, müssen Sie Eclipse den Rechner angeben, über den der Zugriff außerhalb des privaten Netzwerks erfolgen soll, den sogenannten Proxy HTTP. Dies geschieht mit der Option [Window -> Preferences -> Internet]:

Man setzt ein Häkchen bei (1), wenn man sich in einem privaten Netzwerk befindet. In (2) gibt man den Namen des Rechners an, der den Proxy HTTP unterstützt, und in (3) dessen Listening-Port. Schließlich gibt man in (4) die Rechner an, für die der Proxy nicht genutzt werden soll – also Rechner, die sich im selben privaten Netzwerk befinden wie der Rechner, mit dem man gerade arbeitet.
Wir erstellen nun die Datei [index.html] für die Startseite.
3.2. Erstellen einer Startseite
Wir klicken mit der rechten Maustaste auf den Ordner „[WebContent]“ und wählen dann die Option „[New -> Other]“:

Wir wählen den Typ „[HTML]“ aus und führen „[Next]“ aus ->

Oben wählen wir den übergeordneten Ordner [WebContent] unter (1) oder (2) aus und geben dann unter (3) den Namen der zu erstellenden Datei an. Anschließend fahren wir mit der nächsten Seite des Assistenten fort:

Mit (1) können wir eine Datei HTML erstellen, die bereits mit den Angaben aus (2) vorbelegt ist. Wenn wir das Häkchen bei (1) entfernen, wird eine leere Datei HTML erstellt. Wir lassen das Häkchen bei (1) gesetzt, um von einem Code-Gerüst zu profitieren. Wir schließen den Assistenten mit [Finish] ab. Die Datei [index.html] wird daraufhin erstellt:

mit folgendem Inhalt:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
Wir ändern diese Datei wie folgt:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Application personne</title>
</head>
<body>
Application personne active...
<br>
<br>
Vous êtes sur la page d'accueil
</body>
</html>
3.3. Test der Startseite
Falls sie nicht vorhanden ist, rufen wir die Ansicht [Servers] mit der Option [Window - > Show View -> Other -> Servers] auf und klicken dann mit der rechten Maustaste auf den Tomcat 5.5-Server:

Mit der oben genannten Option [Add and Remove Objects] können Webanwendungen zum Tomcat-Server hinzugefügt oder von diesem entfernt werden:

Die in Eclipse bekannten Webprojekte werden unter (1) angezeigt. Sie können über (2) auf dem Tomcat-Server registriert werden. Die beim Tomcat-Server registrierten Webanwendungen werden unter (4) angezeigt. Sie können über (3) deregistriert werden. Registrieren wir das Projekt [personne]:

und schließen wir den Registrierungsassistenten mit [Finish] ab. Die Ansicht [Servers] zeigt, dass das Projekt [personne] auf Tomcat registriert wurde:

Starten wir nun den Tomcat-Server:
![]() | ![]() |
Starten wir den Webbrowser:

und rufen wir dann die URL [http://localhost:8080/personne] auf. Diese URL ist die Startseite der Webanwendung. Es wird kein Dokument angefordert. In diesem Fall wird die Startseite der Anwendung angezeigt. Falls diese nicht existiert, wird eine Fehlermeldung ausgegeben. Hier existiert die Startseite. Es handelt sich um die Datei [index.html], die wir zuvor erstellt haben. Das Ergebnis sieht wie folgt aus:

Es entspricht den Erwartungen. Rufen wir nun dieselbe URL in einem Browser außerhalb von Eclipse auf:

Die Webanwendung [personne] ist somit auch außerhalb von Eclipse bekannt.
3.4. Erstellen eines Formulars HTML
Wir erstellen nun ein statisches Dokument HTML [formulaire.html] im Ordner [personne]:

Zur Erstellung folgen wir der in Abschnitt 3.2 auf Seite 33 beschriebenen Vorgehensweise. Der Inhalt lautet wie folgt:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Retablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
Der oben genannte Code HTML entspricht dem folgenden Formular:

Typ HTML | Name | Code HTML | Rolle | |
<input type="text"> | txtNom | Zeile 14 | Namenseingabe | |
<input type= "text "> | txtAge | Zeile 18 | Eingabe des Alters | |
<input type="submit"> | Zeile 23 | Übermittlung der eingegebenen Werte an den Server unter der URL /personne1/main | ||
<input type="reset"> | Zeile 24 | um die Seite in den Zustand zurückzusetzen, in dem sie ursprünglich vom Browser empfangen wurde | ||
<input type="button"> | Zeile 25 | um den Inhalt der Eingabefelder [1] und [2] zu löschen |
Speichern wir das Dokument im Ordner <person>/WebContent. Starten wir Tomcat, falls erforderlich. Rufen wir mit einem Browser die Seite URL unter http://localhost:8080/personne/formulaire.html auf:

Die Client-Server-Architektur dieser einfachen Anwendung sieht wie folgt aus:

Der Webserver befindet sich zwischen dem Benutzer und der Webanwendung und wurde hier nicht dargestellt. [formulaire.html] ist ein statisches Dokument, das bei jeder Anfrage des Clients denselben Inhalt liefert. Ziel der Webprogrammierung ist es, Inhalte zu generieren, die auf die Anfrage des Clients zugeschnitten sind. Diese Inhalte werden dann programmgesteuert erzeugt. Eine erste Lösung besteht darin, anstelle der statischen Datei HTML eine JSP-Seite (Java Server Page) zu verwenden. Dies werden wir nun betrachten.
3.5. Erstellung einer Seite JSP
Lesezeichen [ref1]: Kapitel 1, Kapitel 2: 2.2, 2.2.1, 2.2.2, 2.2.3, 2.2.4
Die bisherige Client-Server-Architektur wird wie folgt umgestaltet:

Eine Seite JSP ist eine parametrisierte Form der Seite HTML. Bestimmte Elemente der Seite erhalten ihren Wert erst zur Laufzeit. Diese Werte werden programmgesteuert berechnet. Es handelt sich also um eine dynamische Seite: Aufeinanderfolgende Aufrufe der Seite können zu unterschiedlichen Antworten führen. Als Antwort bezeichnen wir hier die vom Client-Browser angezeigte Seite HTML. Letztendlich erhält der Browser immer ein Dokument HTML. Dieses Dokument HTML wird vom Webserver ausgehend von der Seite JSP generiert. Diese dient als Vorlage. Ihre dynamischen Elemente werden durch ihre tatsächlichen Werte zum Zeitpunkt der Generierung des Dokuments HTML ersetzt.
Um eine Seite JSP zu erstellen, klicken wir mit der rechten Maustaste auf den Ordner [WebContent] und wählen dann die Option [New -> Other]:

Wir wählen den Typ [JSP] und führen [Next] aus ->

Oben wählen wir den übergeordneten Ordner [WebContent] unter (1) oder (2) aus und geben dann unter (3) den Namen der zu erstellenden Datei an. Anschließend fahren wir mit der nächsten Seite des Assistenten fort:

Mit (1) können wir eine Datei JSP erstellen, die bereits mit den Angaben aus (2) vorbelegt ist. Wenn wir das Häkchen bei (1) entfernen, wird eine leere Datei JSP erstellt. Wir lassen das Häkchen bei (1) gesetzt, um von einem Code-Gerüst zu profitieren. Wir schließen den Assistenten mit [Finish] ab. Die Datei [formulaire.jsp] wird daraufhin erstellt:

mit folgendem Inhalt:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
Zeile 1 gibt an, dass es sich um eine Seite JSP handelt. Wir wandeln den obigen Text wie folgt um:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// Hier werden die Parameter abgerufen
String nom=request.getParameter("txtNom");
if(nom==null) nom="inconnu";
String age=request.getParameter("txtAge");
if(age==null) age="xxx";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
Das ursprünglich statische Dokument ist nun durch das Einfügen von Java-Code dynamisch geworden. Bei dieser Art von Dokument gehen wir immer wie folgt vor:
- Wir fügen gleich zu Beginn des Dokuments Java-Code ein, um die für die Anzeige des Dokuments erforderlichen Parameter abzurufen. Diese befinden sich häufig im Objekt „request“. Dieses Objekt repräsentiert die Anfrage des Clients. Diese kann mehrere Servlets und JSP-Seiten durchlaufen haben, die sie möglicherweise ergänzt haben. In diesem Fall erreicht sie uns direkt vom Browser.
- Der Code HTML folgt im Anschluss. Meistens beschränkt er sich darauf, zuvor im Java-Code berechnete Variablen mithilfe der Tags <%= variable %> anzuzeigen. Dabei ist zu beachten, dass das Gleichheitszeichen = direkt an das Prozentzeichen % angehängt wird. Dies ist eine häufige Fehlerquelle.
Was bewirkt das vorherige dynamische Dokument?
- Zeilen 6–9: Es entnimmt der Abfrage zwei Parameter namens [txtNom] und [txtAge] und speichert deren Werte in den Variablen [nom] (Zeile 6) und [age] (Zeile 8). Wenn er die Parameter nicht findet, weist er den zugehörigen Variablen Standardwerte zu.
- Im folgenden Code HTML (Zeilen 25 und 29) wird der Wert der beiden Variablen [nom, age] ausgegeben.
Führen wir einen ersten Test durch. Starten wir gegebenenfalls Tomcat und rufen wir dann mit einem Browser die Seite URL unter http://localhost:8080/personne/formulaire.jsp auf:

Das Dokument formulaire.jsp wurde ohne Übergabe von Parametern aufgerufen. Daher wurden die Standardwerte angezeigt. Rufen wir nun das Dokument URL aufhttp://localhost:8080/personne/formulaire.jsp?txtNom=martin&txtAge=14:

Diesmal haben wir dem Dokument formulaire.jsp die Parameter txtNom und txtAge übergeben, die es erwartet. Es hat sie daher angezeigt. Es ist bekannt, dass es zwei Methoden gibt, um Parameter an ein Webdokument zu übergeben: GET und POST. In beiden Fällen befinden sich die übergebenen Parameter im vordefinierten Objekt „request“. Hier wurden sie über die Methode GET übergeben.
3.6. Erstellung eines Servlets
Literaturhinweise zu [ref1]: Kapitel 1, Kapitel 2: 2.1, 2.1.1, 2.1.2, 2.3.1
In der vorherigen Version wurde die Anfrage des Clients von einer Seite namens JSP verarbeitet. Beim ersten Aufruf dieser Seite erstellt der Webserver – in diesem Fall Tomcat – aus dieser Seite eine Java-Klasse und kompiliert diese. Das Ergebnis dieser Kompilierung verarbeitet schließlich die Anfrage des Clients. Die aus der Seite JSP generierte Klasse ist ein Servlet, da sie die Schnittstelle [javax.Servlet] implementiert:

Die Client-Anfrage kann von jeder Klasse verarbeitet werden, die diese Schnittstelle implementiert. Wir erstellen nun eine solche Klasse: ServletFormulaire. Die bisherige Client-Server-Architektur wird wie folgt umgestaltet:

Bei der seitenbasierten Architektur JSP wurde das an den Client gesendete Dokument HTML vom Webserver anhand der Seite JSP generiert, die als Vorlage diente. Hier wird das an den Client gesendete Dokument HTML vollständig vom Servlet generiert.
3.6.1. Erstellung des Servlets
Klicken Sie in Eclipse mit der rechten Maustaste auf den Ordner „[src]“ und wählen Sie die Option zum Erstellen einer Klasse:

Anschließend definieren wir die Eigenschaften der zu erstellenden Klasse:

In (1) geben wir einen Paketnamen ein, in (2) den Namen der zu erstellenden Klasse. Diese muss von der in (3) angegebenen Klasse abgeleitet sein. Es ist nicht notwendig, den vollständigen Namen dieser Klasse selbst einzugeben. Über die Schaltfläche (4) können wir auf die Klassen zugreifen, die sich derzeit im Ordner „Classpath“ der Webanwendung befinden:

In (1) gibt man den Namen der gesuchten Klasse ein. In (2) erhält man die Klassen aus dem Classpath, deren Name die in (1) eingegebene Zeichenfolge enthält.
Nach Bestätigung des Erstellungsassistenten wird das Webprojekt [personne] wie folgt geändert:

Die Klasse [ServletFormulaire] wurde mit einem Code-Gerüst erstellt:

Der obige Screenshot zeigt, dass Eclipse in der Zeile, in der die Klasse deklariert wird, einen Fehler mit der Nummer [warning] anzeigt. Klicken wir auf das Symbol (Glühbirne), das auf diesen Fehler [warning] hinweist:

Nach dem Klicken auf (1) werden uns in (2) Lösungen zum Beheben des Fehlers [warning] vorgeschlagen. Wählt man eine davon aus, wird in (3) die Codeänderung angezeigt, die diese Auswahl zur Folge hat.
Java 1.5 hat Änderungen an der Java-Sprache mit sich gebracht, und was in einer früheren Version korrekt war, kann nun zu [warnings] führen. Diese weisen nicht auf Fehler hin, die die Kompilierung der Klasse verhindern könnten. Sie dienen dazu, den Entwickler auf Stellen im Code aufmerksam zu machen, die verbessert werden könnten. Der vorliegende [warning] weist darauf hin, dass eine Klasse eine Versionsnummer haben sollte. Diese wird für die Serialisierung/Deserialisierung von Objekten verwendet, c.a.d. Wenn ein im Speicher befindliches Java-Objekt .class in eine Bitfolge umgewandelt werden soll, die sequenziell in einem Schreibstrom gesendet wird, oder umgekehrt, wenn ein im Speicher befindliches Java-Objekt .class aus einer Bitfolge erstellt werden soll, die sequenziell aus einem Lesestrom gelesen wird. All dies ist von unseren aktuellen Anliegen weit entfernt. Daher werden wir den Compiler anweisen, diese Warnung zu ignorieren, indem wir die Lösung [Add @SuppressWarnings ...] wählen. Der Code sieht dann wie folgt aus:

Es gibt kein [warning] mehr. Die hinzugefügte Zeile wird als „Annotation“ bezeichnet, ein Konzept, das mit Java 1.5 eingeführt wurde. Wir werden diesen Code später vervollständigen.
3.6.2. Classpath eines Eclipse-Projekts
Der Classpath einer Java-Anwendung umfasst alle Ordner und archives.jar, die durchsucht werden, wenn der Compiler die Anwendung kompiliert oder wenn die JVM sie ausführt. Diese beiden Classpath sind nicht unbedingt identisch, da bestimmte Klassen nur zur Ausführung und nicht zur Kompilierung benötigt werden. Sowohl der Java-Compiler als auch die JVM verfügen über ein Argument, mit dem die Classpath der zu kompilierenden oder auszuführenden Anwendung angegeben werden kann. Für den Benutzer mehr oder weniger transparent sorgt Eclipse für die Erstellung und Übergabe dieses Arguments an die JVM.
Wie kann man die Elemente des Classpath eines Eclipse-Projekts ermitteln? Mit der Option [<projet> / Build Path / Configure Build Path]:

Wir erhalten dann den folgenden Konfigurationsassistenten:

Über die Registerkarte (1) „[Libraries]“ lässt sich die Liste der .jar-Archive festlegen, die zum Classpath der Anwendung gehören. Diese werden dann von der JVM durchsucht, wenn die Anwendung eine Klasse anfordert. Mit den Schaltflächen [2] und [3] können Archive zum Classpath hinzugefügt werden. Mit der Schaltfläche [2] können Archive ausgewählt werden, die sich in den Ordnern der von Eclipse verwalteten Projekte befinden, während mit der Schaltfläche [3] beliebige Archive aus dem Dateisystem des Computers ausgewählt werden können.
Oben werden drei Bibliotheken (Libraries) angezeigt:
- [JRE System Library]: Basisbibliothek für Java-Projekte in Eclipse:

- [Tomcat v5.5 runtime]: Vom Tomcat-Server bereitgestellte Bibliothek. Sie enthält die für die Webentwicklung erforderlichen Klassen. Diese Bibliothek ist in jedem Eclipse-Webprojekt enthalten, das mit dem Tomcat-Server verknüpft wurde.

Es ist das Archiv [servlet-api.jar], das die Klasse [javax.servlet.http.HttpServlet] enthält, die die übergeordnete Klasse der Klasse [ServletFormulaire] ist, die wir gerade erstellen. Da sich dieses Archiv im Classpath der Anwendung befindet, konnte es im unten gezeigten Assistenten als übergeordnete Klasse vorgeschlagen werden.

Wäre dies nicht der Fall gewesen, wäre sie nicht in den Vorschlägen für [2] erschienen. Wenn man also in diesem Assistenten eine übergeordnete Klasse referenzieren möchte und diese nicht vorgeschlagen wird, liegt das entweder daran, dass man sich beim Namen dieser Klasse geirrt hat, oder daran, dass das Archiv, das sie enthält, nicht im Classpath der Anwendung enthalten ist.
- [Web App Libraries] enthält die Archive, die sich im Ordner [WEB-INF/lib] des Projekts befinden. Hier ist er leer:

Die Archive des Eclipse-Projekts „Classpath“ sind im Projekt-Explorer vorhanden. Zum Beispiel für das Webprojekt „[personne]“:

Über den Projekt-Explorer haben wir Zugriff auf den Inhalt dieser Archive:

Wie oben zu sehen ist, enthält das Archiv [servlet-api.jar] die Klasse [javax.servlet.http.HttpServlet].
3.6.3. Konfiguration des Servlets
Lektüre [ref1]: Kapitel 2: 2.3, 2.3.1, 2.3.2, 2.3.3, 2.3.4
Die Datei [WEB-INF/web.xml] dient zur Konfiguration der Webanwendung:

Diese Datei für das Projekt [personne] sieht derzeit wie folgt aus (siehe Seite 32):
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Sie gibt lediglich das Vorhandensein einer Startseite an (Zeile 8). Wir passen sie an, um Folgendes anzugeben:
- die Existenz des Servlets [ServletFormulaire]
- die von diesem Servlet verarbeiteten URL
- die Initialisierungsparameter des Servlets
Die Datei web.xml unserer Anwendung „person“ sieht dann wie folgt aus:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>formulairepersonne</servlet-name>
<url-pattern>/formulaire</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Die wichtigsten Punkte dieser Konfigurationsdatei sind folgende:
- Die Zeilen 7–24 beziehen sich auf das Vorhandensein des Servlets [ServletFormulaire]
- Zeilen 7–20: Die Konfiguration eines Servlets erfolgt zwischen den Tags <servlet> und </servlet>. Eine Anwendung kann mehrere Servlets und somit ebenso viele Konfigurationsabschnitte <servlet>...</servlet> enthalten.
- Zeile 8: Der Tag <servlet-name> legt einen Namen für das Servlet fest – dieser kann beliebig gewählt werden
- Zeilen 9–11: Der Tag <servlet-class> gibt den vollständigen Namen der Klasse an, die dem Servlet entspricht. Tomcat sucht diese Klasse in der Datei Classpath des Webprojekts [personne]. Es findet sie in [build/classes]:
![]()
- Zeilen 12–15: Das Tag <init-param> dient dazu, Konfigurationsparameter an das Servlet zu übergeben. Diese werden in der Regel in der init-Methode des Servlets gelesen, da dessen Konfigurationsparameter bereits beim ersten Laden bekannt sein müssen.
- Zeilen 13–14: Das Tag <param-name> legt den Namen des Parameters fest und <param-value> dessen Wert.
- Die Zeilen 12–15 definieren einen Parameter [defaultNom,"inconnu"] und die Zeilen 16–19 einen Parameter [defaultAge,"XXX"]
- Zeilen 21–24: Das Tag <servlet-mapping> dient dazu, ein Servlet (servlet-name) einem Muster URL (url-pattern) zuzuordnen. Hier ist das Muster einfach. Es besagt, dass immer dann, wenn eine URL die Form /formulaire hat, das Servlet „formulairepersonne“ (c.a.d) verwendet werden muss. Die Klasse [istia.st.servlets.ServletFormulaire] (Zeilen 8–11). Es gibt also nur eine URL, die vom Servlet „[formulairepersonne]“ akzeptiert wird.
3.6.4. Der Code des Servlets [ServletFormulaire]
Das Servlet [ServletFormulaire] wird folgenden Code haben:
Schon beim bloßen Lesen des Servlets fällt auf, dass es wesentlich komplexer ist als die entsprechende Seite JSP. Das gilt generell: Ein Servlet ist nicht dafür geeignet, HTML-Code zu generieren. Dafür sind die JSP-Seiten vorgesehen. Wir werden später noch darauf zurückkommen. Lassen Sie uns einige wichtige Punkte des oben genannten Servlets näher erläutern:
- Wenn ein Servlet zum ersten Mal aufgerufen wird, wird seine Methode `init` (Zeile 20) aufgerufen. Dies ist der einzige Fall, in dem sie aufgerufen wird.
- Wurde das Servlet über die Methode HTTP GET aufgerufen, wird die Methode doGet (Zeile 32) aufgerufen, um die Anfrage des Clients zu bearbeiten.
- Wenn das Servlet über die Methode HTTP POST aufgerufen wurde, wird die Methode doPost (Zeile 82) aufgerufen, um die Anfrage des Clients zu bearbeiten.
Die Methode „init“ dient hier dazu, in [web.xml] die Werte der Initialisierungsparameter „defaultNom“ und „defaultAge“ abzurufen. Die beim ersten Laden des Servlets ausgeführte Methode „init“ ist der richtige Ort, um den Inhalt der Datei „[web.xml]“ abzurufen.
- Zeile 22: Die Konfiguration [config] des Webprojekts wird abgerufen. Dieses Objekt spiegelt den Inhalt der Anwendungsdatei [WEB-INF/web.xml] wider.
- Zeile 23: Aus dieser Konfiguration wird der Wert vom Typ String des Parameters „defaultNom“ abgerufen. Dieser Parameter enthält den Namen einer Person. Falls er nicht existiert, erhält man den Wert null.
- Zeilen 24–25: Wenn der Parameter „defaultNom“ nicht existiert, wird der Variablen [defaultNom] ein Standardwert zugewiesen.
- Zeilen 26–29: Das Gleiche gilt für den Parameter „defaultAge“.
Die Methode doPost verweist auf die Methode doGet. Das bedeutet, dass der Client seine Parameter wahlweise über eine POST oder eine GET senden kann.
Die Methode doGet:
- Zeile 32: Die Methode erhält zwei Parameter: „request“ und „response“. „request“ ist ein Objekt, das die gesamte Anfrage des Kunden repräsentiert. Es ist vom Typ „HttpServletRequest“, bei dem es sich um eine Schnittstelle handelt. „response“ ist vom Typ „HttpServletResponse“, ebenfalls eine Schnittstelle. Das Objekt „response“ dient dazu, eine Antwort an den Kunden zu senden.
- request.getParameter("param") dient dazu, aus der Anfrage des Kunden den Wert des Parameters mit dem Namen „param“ abzurufen. In Zeile 36 wird der Wert des Parameters „txtNom“ abgerufen, in Zeile 40 der Wert des Parameters „txtAge“. Sind diese Parameter in der Anfrage nicht vorhanden, wird der Wert „null“ als Parameterwert verwendet.
- Zeilen 37–39: Wenn der Parameter „txtNom“ nicht in der Abfrage enthalten ist, wird der Variablen „nom“ der in der Methode „init“ initialisierte Standardname „defaultNom“ zugewiesen. Das Gleiche gilt in den Zeilen 41–43 für das Alter.
- Zeile 45: response.setContentType(String) dient dazu, den Wert des Headers HTTP „Content-Type“ festzulegen. Dieser Header teilt dem Client mit, um welche Art von Dokument es sich handelt, das er erhalten wird. Der Typ „text/html“ weist auf ein HTML-Dokument hin.
- Zeile 46: response.getWriter() dient dazu, einen Schreibstrom zum Client zu erhalten
- Zeilen 47–78: Das an den Client zu sendende Dokument HTML wird in den in Zeile 46 erstellten Schreibstrom geschrieben.
Die Kompilierung dieses Servlets erzeugt eine .class-Datei im Ordner „[build/classes]“ des Projekts „[personne]“:

Der Leser wird gebeten, die Java-Hilfe zu Servlets zu konsultieren. Dabei kann man sich von Tomcat unterstützen lassen. Auf der Startseite von Tomcat 5 befindet sich ein Link [Documentation]:

Dieser Link führt zu einer Seite, die der Leser erkunden sollte. Der Link zur Servlet-Dokumentation lautet wie folgt:

3.6.5. Test des Servlets
Wir sind bereit für einen Test. Starten wir bei Bedarf den Tomcat-Server.

Rufen wir dann mit einem Browser die URLs URL und [http://localhost:8080/personne/formulaire] auf. Wir rufen hier die URL [/formulaire] aus dem Kontext [/personne] auf. Die Datei [web.xml] dieses Kontexts gibt an, dass die URL [/formulaire] vom Servlet mit dem Namen [formulairepersonne] verarbeitet wird. In derselben Datei wird angegeben, dass dieses Servlet die Klasse [istia.st.servlets.ServletFormulaire] ist. Tomcat wird also diese Klasse mit der Bearbeitung der Client-Anfrage beauftragen. Falls die Klasse noch nicht geladen war, wird sie geladen. Sie bleibt dann für zukünftige Anfragen im Speicher.
Mit dem in Eclipse integrierten Browser erhält man folgendes Ergebnis:

Wir erhalten die Standardwerte für Name und Alter, die in der Datei [web.xml] hinterlegt sind. Rufen wir nun die Dateien URL und [http://localhost:8080/personne/formulaire?txtNom=tintin&txtAge=30] auf:

Diesmal erhalten wir die in der Anfrage übergebenen Parameter. Der Leser wird gebeten, den Code des Servlets [ServletFormulaire] noch einmal durchzulesen, falls er diese beiden Ergebnisse nicht versteht.
3.6.6. Automatisches Neuladen des Webanwendungskontexts
Starten wir Tomcat:

und ändern wir anschließend den Code des Servlets wie folgt:
- Zeile 8 wurde geändert
Speichern wir die neue Klasse. Diese Speicherung führt dazu, dass Eclipse die Klasse [ServletFormulaire] automatisch neu kompiliert, was von Tomcat erkannt wird. Anschließend wird der Kontext der Webanwendung [personne] neu geladen, um die Änderungen zu berücksichtigen. Dies wird in den Protokollen der Ansicht [console] angezeigt:

Rufen wir die URL [http://localhost:8080/personne/formulaire] auf, ohne Tomcat neu zu starten:

Die vorgenommene Änderung wurde erfolgreich übernommen.
Nun ändern wir die Datei [web.xml] wie folgt:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<servlet>
<servlet-name>formulairepersonne</servlet-name>
...
<init-param>
<param-name>defaultNom</param-name>
<param-value>INCONNU</param-value>
</init-param>
...
</servlet>
...
</web-app>
- Zeile 12 wurde geändert
Nachdem dies erledigt ist, speichern wir die neue Datei [web.xml]. In der Ansicht [console] gibt es keinen Eintrag im Protokoll, der auf das Neuladen des Anwendungskontexts hinweist. Rufen wir die URL [http://localhost:8080/personne/formulaire] auf, ohne Tomcat neu zu starten:

Die vorgenommene Änderung wurde nicht berücksichtigt. Starten wir Tomcat neu: [clic droit sur serveur -> Restart -> Start]:

und rufen wir anschließend erneut die URL [http://localhost:8080/personne/formulaire] auf:

Diesmal ist die in [web.xml] vorgenommene Änderung sichtbar.
Eine Änderung an [web.xml] führt also nicht zu einem automatischen Neuladen der Anwendung, bei dem die neue Konfigurationsdatei berücksichtigt würde. Um das Neuladen der Webanwendung zu erzwingen, kann man Tomcat wie zuvor beschrieben neu starten, was jedoch ein recht langwieriger Vorgang ist. Es ist besser, das Tool [manager] zur Verwaltung der in Tomcat bereitgestellten Anwendungen zu verwenden. Damit dies möglich ist, muss Tomcat in Eclipse so konfiguriert worden sein, wie es in Abschnitt 2.5 gezeigt wurde.
Rufen Sie zunächst mit dem internen Browser von Eclipse die URL [http://localhost:8080] auf und folgen Sie dann dem Link [Tomcat Manager], wie am Ende von Abschnitt 2.5 erläutert:

Öffnen wir einen zweiten Browser mit der URL [clic droit sur le navigateur -> New Editor]:
![]() | ![]() |
Rufen wir in diesem zweiten Browser die URL [http://localhost:8080/formulaire] auf:

Ändern wir die Datei [web.xml] wie folgt und speichern wir sie anschließend:
<!-- ServletFormulaire -->
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>YYY</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
Rufen wir anschließend die URL [http://localhost:8080/formulaire] erneut auf. Wir können feststellen, dass die Änderung nicht übernommen wurde. Wechseln wir nun zum ersten Browser und laden wir die Anwendung [personne] neu:

Rufen wir dann die URL [http://localhost:8080/formulaire] mit dem zweiten Browser erneut auf:

Die Änderung an [web.xml] wurde berücksichtigt. In der Praxis ist es sinnvoll, einen Browser mit der Tomcat-Anwendung [manager] geöffnet zu haben, um solche Fälle zu bewältigen.
3.7. Zusammenarbeit zwischen Servlet und Seiten JSP
Literaturhinweise zu [ref1]: Kapitel 2: 2.3.7
Kehren wir zu den beiden untersuchten Architekturen zurück:

Keine dieser beiden Architekturen ist zufriedenstellend. Beide weisen den Nachteil auf, dass sie zwei Technologien vermischen: die der Java-Programmierung, die sich um die Logik der Webanwendung kümmert, und die der HTML-Codierung, die für die Darstellung von Informationen in einem Browser zuständig ist.
- Die auf der Seite JSP basierende Lösung [1] hat den Nachteil, dass HTML-Code und Java-Code innerhalb derselben Seite vermischt werden. Im behandelten Beispiel, das sehr einfach war, ist dies nicht aufgefallen. Hätte [formulaire.jsp] jedoch die Gültigkeit der Parameter [txtNom, txtAge] der Client-Anfrage überprüfen müssen, wären wir gezwungen gewesen, Java-Code in die Seite einzufügen. Das wird sehr schnell unüberschaubar.
- Die auf einem Servlet basierende Lösung [2] weist dasselbe Problem auf. Obwohl die Klasse ausschließlich Java-Code enthält, muss sie ein Dokument HTML generieren. Auch hier gilt: Sofern das HTML-Dokument nicht sehr einfach aufgebaut ist, wird seine Generierung kompliziert und nahezu unmöglich zu warten.
Wir werden die Vermischung der Technologien Java und HTML vermeiden, indem wir die folgende Architektur verwenden:

- Der Benutzer sendet seine Anfrage an das Servlet. Dieses verarbeitet sie und erstellt die Werte der dynamischen Parameter der Seite JSP [formulaire.jsp], die zur Generierung der Antwort HTML an den Client dienen. Diese Werte bilden das sogenannte Seitenmodell der Seite JSP.
- Sobald das Servlet seine Arbeit beendet hat, fordert es die Seiten JSP und [formulaire.jsp] auf, die Antwort HTML für den Client zu generieren. Gleichzeitig übermittelt es ihr die Elemente, die die Seite JSP zur Generierung dieser Antwort benötigt – jene Elemente, die das Seitenmodell bilden.
Wir werden nun diese neue Architektur näher betrachten.
3.7.1. Das Servlet [ServletFormulaire2]
In der oben dargestellten Architektur wird das Servlet den Namen [ServletFormulaire2] tragen. Es wird im selben Projekt [personne] erstellt wie zuvor, ebenso wie alle nachfolgenden Servlets:

[ServletFormulaire2] wird zunächst durch Kopieren und Einfügen von [ServletFormulaire] in Eclipse erstellt:
- Auswahl von [ServletFormulaire.java] -> Rechtsklick -> Kopieren
- [istia.st.servlets.personne] auswählen -> Rechtsklick -> Einfügen -> Namen in [ServletFormulaire2.java] ändern
Anschließend ändern wir den Code von [ServletFormulaire2] wie folgt:
Nur der Teil zur Generierung der Antwort HTTP hat sich geändert (Zeilen 44–46):
- Zeile 46: Die Generierung der Antwort wird der Seite JSP formulaire2.jsp übertragen. Diese Seite, die noch nicht behandelt wurde, ist dafür zuständig, die in der Client-Anfrage abgerufenen Parameter anzuzeigen: einen Namen (Zeilen 35–38) und ein Alter (Zeilen 39–42).
- Diese beiden Werte werden in die Attribute der Anfrage [request] eingefügt, die mit Schlüsseln verknüpft sind. Die Attribute einer Anfrage werden wie ein Wörterbuch verwaltet.
- Zeile 44: Der Name wird in die Abfrage aufgenommen und dem Schlüssel „nom“ zugeordnet
- Zeile 45: Das Alter wird in die Abfrage eingefügt und dem Schlüssel „Alter“ zugeordnet
- Zeile 46: Fordert die Anzeige der Seite JSP [formulaire2.jsp] an. Als Parameter werden folgende Werte übergeben:
- die Anfrage [request] des Kunden, wodurch die Seite JSP Zugriff auf deren Attribute erhält, die soeben vom Servlet initialisiert wurden
- die Antwort [response], wodurch die Seite JSP die Antwort HTTP an den Kunden generieren kann
Sobald die Klasse [ServletFormulaire2] geschrieben ist, erscheint ihr kompilierter Code in [build/classes]:

3.7.2. Die Seite JSP [formulaire2.jsp]
Die Seite JSP formulaire2.jsp wird durch Kopieren und Einfügen der Seite [formulaire.jsp] erstellt

und anschließend wie folgt umgewandelt:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// Die für die Anzeige erforderlichen Werte werden abgerufen
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Personne - formulaire2</title>
</head>
<body>
<center>
<h2>Personne - formulaire2</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
Im Vergleich zu [formulaire.jsp] haben sich nur die Zeilen 4–8 geändert:
- Zeile 6: Ruft den Wert des Attributs „nom“ aus der Abfrage [request] ab, das vom Servlet [ServletFormulaire2] erstellt wurde.
- Zeile 7: tut dasselbe für das Attribut „age“
3.7.3. Konfiguration der Anwendung
Die Konfigurationsdatei [web.xml] wird wie folgt geändert:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<!-- ServletFormulaire -->
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXXX</param-value>
</init-param>
</servlet>
<!-- ServletFormulaire 2-->
<servlet>
<servlet-name>formulairepersonne2</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire2
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
<!-- Zuordnung ServletFormulaire -->
<servlet-mapping>
<servlet-name>formulairepersonne</servlet-name>
<url-pattern>/formulaire</url-pattern>
</servlet-mapping>
<!-- Zuordnung ServletFormulaire 2-->
<servlet-mapping>
<servlet-name>formulairepersonne2</servlet-name>
<url-pattern>/formulaire2</url-pattern>
</servlet-mapping>
<!-- Startdateien -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Wir haben den bestehenden Code beibehalten und Folgendes hinzugefügt:
- Zeilen 22–36: einen <servlet>-Abschnitt zur Definition des neuen Servlets ServletFormulaire2
- Zeilen 42–46: einen <servlet-mapping>-Abschnitt, um ihm das Formular „URL /formulaire2“ zuzuordnen
Starten Sie den Tomcat-Server bei Bedarf neu. Wir rufen das URL auf
http://localhost:8080/personne/formulaire2?txtNom=milou&txtAge=10:

Wir erhalten das gleiche Ergebnis wie zuvor, aber die Struktur unserer Anwendung ist nun übersichtlicher: Ein Servlet, das die Anwendungslogik enthält und das Senden der Antwort an den Client an eine Seite mit dem Namen JSP delegiert. Wir werden fortan immer auf diese Weise vorgehen.



