|
Wilhelm-Schickard-Institut
Arbeitsbereich Technische Informatik
|
|
|
|
WS 02/03
|
|
Blatt 4: Servlets
Abgabetermin 16.12.02
Eine allgemeine (nicht technische) Einführung über Servlets findet Ihr
hier.
Zweck der beiden unten vorgestellten Aufgaben ist, daß Ihr erste Erfahrungen mit der Programmierung von Servlets sammelt. In den folgenden Paragraphen findet Ihr das nötige technische Hintergrundwissen für die Programmierung der Aufgaben:
Falls Ihr noch mehr Informationen über Servlet-Programmierung benötigt, ist folgendes Dokument sehr
zu empfehlen:
WebSphere Application Server Guide, v. 1.0 (PDF) - Kapitel 3, Servlet Programmierung
und noch weiter Links auf Dokumentation:
Die Aufgaben werden betreut von:
Oliver Avieny
und
Denis Reimann
Wenn Ihr Fragen habt, meldet Euch sich einfach per eMail oder wärend der Anwesenheitszeit.(Do 9-12 Poolraum Sand 6/7)
|
|
Was sind Servlets?
Java Servlets sind spezielle Java-Programme, deren Zweck die Erweiterung der Funktionalität eines Servers
ist. Diese Programme laufen serverseitig, auf einer Java Virtual Machine (JVM) auf dem Server. Der
Client (Webbrowser) braucht Java nicht zu unterstützen. Eine populäre Beispielanwendung für
Servlets ist die Anbindung eines Servers an eine Datenbank.
Zur Kommunikation zwischen Servlet und Server wurde eine plattformunabhängige Schnittstelle definiert, die
Java Servlet API. Ein einmal programmiertes Servlet kann also prinzipiell auf jedem Server laufen, der
diese API unterstützt.
Die Java Servlet API besteht aus folgenden packages:
-
javax.servlet: Enthält Klassen für die Implementierung von generischen
(protokollunabhängigen) Servlets.
-
javax.servlet.http: Enthält Klassen für die Implementierung von Servlets, welche
das HTTP-Protokoll benutzen (HttpServlets).
|
|
HttpServlets
Kurzeinführung in das HTTP-Protokoll: Das HTTP-Protokoll ist ein einfaches, verbindungsloses
Protokoll. Verbindungslos bedeutet, daß zwischen Client (Webbrowser) und Server keine permanente,
sondern nur eine temporäre Verbindung besteht.
Wenn der Client etwas vom Server will, schickt er eine sogenannte request an den Server. Eine request
enthält einen HTTP-Befehl, die sog. method, welche angibt, was der Server tun soll. Nachdem der
Server den Befehl verarbeitet hat, antwortet er mit einer response.
Die meistbenutzten HTTP-Befehle sind die Kommandos GET und POST. Etwas einfach
formuliert dient das GET Kommando dazu, Daten vom Server zu bekommen, während POST
benutzt wird, um Daten an den Server zu senden.
HttpServlets erstellen: Ein HttpServlet erhält man, indem man die Klasse HttpServlet
aus dem package javax.servlet.http erweitert. Ein HttpServlet erhält requests
von einem Webserver (s. Grafik unten) und schickt responses zurück. Die wichtigsten
Methoden dieser Klasse sind:
-
doGet(HttpServletRequest, HttpServletResponse): Verarbeiten von GET requests.
-
doPost(HttpServletRequest, HttpServletResponse): Verarbeiten von POST requests (also
requests, die Daten an das Servlet senden).
-
init(ServletConfig): Wird einmal aufgerufen, wenn das Servlet vom Server geladen wird. Hier kann
man Befehle zur Initialisierung des Servlets plazieren (z.B. Daten aus einer Datenbank holen, die sich
während der Laufzeit nicht ändern).
-
destroy(): Wird einmal aufgerufen, wenn das Servlet vom Server aus dem
Speicher entfernt wird.
Hinweis: In den Aufgaben werdet Ihr nur doGet() bzw. doPost() benötigen.
Wichtig ist zu wissen, daß jedes Servlet-Objekt vom Server nur einmal erzeugt (instanziert)
wird, und danach mehrere Threads des Servers (eins pro request) u.U. gleichzeitig auf dieses Objekt zugreifen.
Falls also member-Variablen (Klassenvariablen) des Servlets verändert werden, ist es notwendig, die
jeweiligen Methoden als synchronized zu deklarieren, um die Konsistenz der Daten zu gewährleisten.
Lokale Variablen, die nur innerhalb von doGet() bzw. doPost() Methoden existieren, sind
davon natürlich nicht betroffen.
Soviel zu Servlets im allgemeinen. Ziel der zweiten Aufgabe auf diesem Blatt ist es, das HttpSession
Objekt kennenzulernen und ein Servlet zu schreiben, welches mit einem (fertigen) Applet kommuniziert.
|
|
Die HttpSession
Die HttpSession ist eines der interessantesten Objekte der Servlet API. Mit Hilfe dieses Objekts
ist es möglich, Daten einem unbekannten Benutzer eindeutig zuzuordnen und über mehrere Schritte zu
bearbeiten (Anwendungsbeispiel: Warenkorb). Dazu wird dem Benutzer ein Cookie mit der ID seiner Session
geschickt. Die Daten der HttpSession bleiben jedoch auf dem Server. Wenn der Benutzer sich wieder
meldet, wird über den Wert des Cookies auf die richtige Session zugegriffen.
All das passiert automatisch und transparent. Als Programmierer muß man sich lediglich um das holen bzw.
erzeugen eines Session-Objekts kümmern, sowie um das Schreiben und Lesen der dort gespeicherten Werte.
Dies macht das Benutzen von Sessions sehr einfach und attraktiv. Nützliche Methoden in diesem Zusammenhang
sind die getSession(boolean) Methode der HttpServletRequest und die verschiedenen
Methoden des HttpSession Objekts.
|
|
Infos zur Applet <-> Servlet Kommunikation
HttpServlets können nicht nur mit Webbrowsern kommunizieren, sondern auch mit Java Applets,
welche im Webbrowser laufen. Zu diesem Zweck stellt das Applet eine Verbindung zum Servlet her. Es gibt mehrere
Möglichkeiten, diese Verbindung herzustellen:
-
Die einfachste Möglichkeit ist, eine HTTP-Verbindung zu benutzen und Daten als Parameter der GET
bzw. POST requests an das Servlet zu senden. Dies ist ziemlich einfach, weil HTTP-Verbindungen
über das Objekt java.net.URLConnection aufgebaut werden können. Falls Ihr sehen wollt,
wie dies konkret geht, könnt Ihr Euch die Datei HttpMessage.java (bei den Rahmenprogrammen)
ansehen, die auch von unserem MasterMind Applet benutzt wird.
Vorteile dieser Methode sind: die einfache Programmierung (Kommunikation über das HTTP-Protokoll) und
sie funktioniert auch durch Firewalls hindurch. Es ist auch möglich, damit Java-Objekte zu
verschicken, falls diese serializable sind. Nachteil ist, daß die Verbindung jedes
Mal vom Applet hergestellt werden muß, da sie nicht dauerhaft ist. U.a. deshalb ist diese Methode auch nicht
gerade besonders effizient.
-
Eine andere Möglichkeit ist die altbewährte Socket-Verbindung. Nachdem das Applet mit dem
Servlet verbunden ist, ist bidirektionale, dauerhafte und effiziente Kommunikation möglich. Sowohl einfache
Daten, als auch Objekte können verschickt werden. Nachteile: Sie funktioniert nicht durch Firewalls,
ist komplizierter zu programmieren (besonders auf der Servlet-Seite), und man muß sein eigenes
Kommunikationsprotokoll entwerfen.
-
Als dritte Möglichkeit kommt die Benutzung der RMI (Remote Method Invocation) Schnittstelle in
Frage. Vorteile: Elegant, weil keine requests/responses, sondern nur Methodenaufrufe benutzt werden und
objektorientiert. Das Servlet kann Methoden des Applets aufrufen. Funktioniert auch durch Firewalls (aber
noch nicht so gut). Nachteile: Kompliziert zu programmieren, da spezielle Stub und Skeleton
Klassen notwendig sind. Außerdem ist eine RMI-NamingRegistry notwendig, um Referenzen auf die Objekte
zu bekommen. Nicht alle Browser unterstützen defaultmäßig RMI (Stand Ende 98). Außerdem
kann das Servlet dann nur mit Java-Clients interagieren.
|
|
Das MasterMind Spiel
In der zweiten Aufgabe werden wir uns mit einem Applet-Servlet Paar befassen, mit dem man MasterMind spielen
kann. Falls Ihr das Spiel nicht kennt, wird es deshalb hier kurz vorgestellt:
Ziel ist es, einen nichtbekannten, fünfstelligen Zahlencode zu finden (der Spielcode). Dazu kann man
beliebig oft einen Spielcode-Kandidaten eingeben. Als Antwort erhält man die Anzahl der Ziffern, die an
richtiger Stelle sind und die Anzahl der Ziffern, die zwar im Spielcode enthalten, aber an falscher Stelle
sind. Hat man 5 Zahlen an richtiger Stelle, so hat man gewonnen.
|
|
Bevor Ihr beginnt:
Im Praktikum benutzen wir Apache als Webserver, gekoppelt mit dem WebSphere Applikationsserver von IBM, welcher
die Servlets ausführt. Angebunden ist eine SQL-Datenbank (DB2), in der die Produkte eines fiktiven Pizza-Lieferdienstes
abgelegt sind. Im Rahmen der ersten Aufgabe werdet Ihr einige Produktbeschreibungen aus der Datenbank holen. Um
dies so einfach wie möglich zu gestalten, gibt es ein package namens pizzasvc.db, das
Klassen enthält, welche die Datenbank auf Objekte abbilden. Mehr dazu in der Aufgabenstellung.

[Das 3-Schichten Modell]
Braucht man extra Klassen? (Ja)
Da die Servlets die Java Servlet API benutzen, braucht Ihr die entsprechenden .jar Dateien. Diese
findet Ihr auf quak.informatik.uni-tuebingen.de unter /usr/opt/home/cspuser/classes.tar.gz.
Die Datei enthält auch das package pizzasvc.db. Ihr solltet ein Verzeichnis in eurem Account
erstellen und das .tar.gz Archiv dort entpacken.
Dann müßt Ihr noch die CLASSPATH Variable auf die .jar Dateien setzen. Im
Beispiel unten befinden sich die Dateien im Verzeichnis myClasses. Der Befehl muß
natürlich in eine Zeile geschrieben werden.
export CLASSPATH=.:/usr/lib/java/lib/classes.zip:
/home/your_id/myClasses/ibmwebas.jar:
/home/your_id/myClasses/jst.jar:
/home/your_id/myClasses/jsdk.jar:
/home/your_id/myClasses/xml4j.jar:
/home/your_id/myClasses/databeans.jar:
/home/your_id/myClasses/
Gibt es Rahmenprogramme? (Ja)
Die Rahmenprogramme für Aufgabe 1 findet Ihr hier und für Aufgabe 2
hier.
Welches JDK kann benutzt werden?
Ihr solltet das IBM JDK 1.1.7B für Linux benutzen. Dies gibt es auf dem Rechner
quak.informatik.uni-tuebingen.de.
Wo muß man die Lösungen ablegen, damit der Server sie findet?
-
Die
.class Dateien Eurer Servlets legt Ihr auf quak, in das Verzeichnis
/usr/opt/IBMWebAS/servlets/aufgaben/user_id, wobei user_id
Eure login ID ist (das Verzeichnis user_id müßt ihr erst noch anlegen).
-
Eure Servlets müssen dem package
aufgaben.user_id angehören, sonst findet
der Server sie nicht!
-
Eure
.html Dateien legt Ihr ebenfalls auf quak in das Verzeichnis
/usr/opt/home/cspuser/public_html/user_id (auch hier müßt ihr das Verzeichnis
user_id erst noch anlegen).
Wie kann man die .html-Dateien/Servlets aufrufen?
-
Damit das ganze funktioniert, müßt Ihr eine HTML-Einstiegsseite in das oben genannte
user_id
Verzeichnis legen und diese mit http://quak.informatik.uni-tuebingen.de/~cspuser/user_id/htmlSeite
aufrufen.
-
Von dieser Einstiegsseite aus und in den folgenden Seiten/Servlets könnt Ihr dann den relativen Pfad
/~cspuser/user_id/Seite benutzen, um .html Seiten aufzurufen.
-
Um Servlets von der Einstiegsseite aufzurufen, müßt Ihr den Pfad
/servlet/aufgaben/user_id/dateiname
(ohne .class) benutzen.
|
|
Ihre Aufgabe:(Beachten Sie die Tips!!!)
Aufgabe 1
In dieser Aufgabe sollt Ihr ein Servlet erstellen, welches anhand des gesendeten Werts aus dem Formular in der
.html Seite Aufg1.html eine Datenbankabfrage startet und eine .html
Seite mit der Liste der Produkte erzeugt. Erweitert dazu das Rahmenprogramm Aufg1Servlet.java.
Folgende Teilschritte sind notwendig:
-
Die Datei
Aufg1.html so anpassen, daß Euer Servlet aufgerufen wird und diese in das
HTML-Verzeichnis legen, wie oben beschrieben.
-
Nun könnt Ihr mit der Programmierung des Servlets fortfahren. Hier sind folgende Schritte notwendig:
-
Den Wert auslesen. Den Namen erfahrt Ihr in der
.html Seite Aufg1.html.
-
Die Datenbank abfragen: Dazu müßt Ihr die dem Wert entsprechende Produkt-Kategorie aus einer
Liste holen. Dann müßt Ihr diese Produkt-Kategorie an die Produkt-Liste übermitteln und
die Datenbankabfrage starten. Die dazu benötigten Objekte sind schon im Rahmenprogramm definiert.
-
Den Cache abschalten und die Antwort generieren.
-
Nach dem Kompilieren des Servlets die
.class Datei im Verzeichnis für Servlets ablegen
(siehe oben) und die .html Seite aufrufen, um es zu testen.
Tips: Schaut Euch zuerst das Rahmenprogramm an. Dann schaut Euch die Dokumentation der Servlet API an,
insbesondere für die Objekte HttpServlet, HttpServletRequest und
HttpServletResponse. Für die Datenbankabfrage schaut in der Dokumentation des package
pizzasvc.db nach. Links sind unten angegeben.
Aufgabe 2
Zu tun ist folgendes: Es gibt ein Applet, welches eine einfache GUI für ein MasterMind Spiel zur
Verfügung stellt. Das Generieren der Spielcodes und das Überprüfen der Spielcode-Kandidaten
übernimmt ein Servlet. Das Applet kommuniziert mit dem Servlet über ein einfaches
Kommunikationsprotokoll, um dessen Dienste zu benutzen. Die Nachrichten des Protokolls werden vom Applet als
Parameter an die request angehängt, mit der das Servlet aufgerufen wird.
Eure Aufgabe ist es, das Protokoll auf der Seite des Servlets zu implementieren. Im folgenden sind die zwei
Nachrichten des Protokolls beschrieben und was für jede zu tun ist. Eine detaillierte Auflistung der
notwendigen Einzelschritte findet Ihr als Kommentare im Rahmenprogramm mmServlet.java, welches
Ihr auch bearbeiten sollt.
Nachricht 1: Parameter "action" mit Wert "code":
In diesem Fall soll das Servlet eine neue Session erstellen (falls noch keine für diesen
Kommunikationspartner erzeugt wurde). Es soll einen neuen Spielcode erzeugen (mit createCode())
und diesen in die Session schreiben. Außerdem soll es die Anzahl der gemachten Spielzüge (Versuche)
auf 0 setzen und in die Session schreiben.
Nachricht 2: Parameter "action" mit Wert "validate" und Parameter "code" mit Wert: ein
möglicher Code (Code-Kandidat).
In dem Fall soll das Servlet:
-
Den Spielcode aus der Session holen.
-
Den Code-Kandidaten aus dem request-Parameter "code" holen.
-
Die Anzahl der gemachten Versuche aus der Session holen, um eins erhöhen und wieder in die Session
schreiben.
-
Spielcode und Code-Kandidaten vergleichen und das Ergebnis an das Servlet zurückschicken. Das Ergebnis
hat folgendes Format: "<Anzahl_gemachte_Spielzüge>,<Zahlen an richtiger Stelle>,<Zahlen
im Code, aber an falscher Stelle>". Für den Vergleich die mitgelieferte Methode
validateCode(..., ...) benutzen.
Zusätzlich müßt Ihr:
-
Das package Eures Servlets anpassen (aufgaben.userID).
-
Das Applet
mmApplet.java anpassen, so daß Euer Servlet aufgerufen wird (Datei
mmApplet.java, String SERVLET_LOC).
-
Möglicherweise die Seite
mmind.html anpassen, so daß Euer Applet aufgerufen
wird.
-
Die entsprechenden Dateien in Eure Verzeichnisse legen:
mmind.html, mmApplet.class
und HttpMessage.class Dateien in das HTML-Verzeichnis und das Servlet ins Servlet-Verzeichnis.
Tips:
-
Die einfachste Art, den Wert der Parameter aus der request zu lesen (ist aber
deprecated), ist
die Methode request.getParameter(parameter_Name), welche ein Object zurückgibt
(Type-Cast notwendig).
-
Um das Servlet zu testen müßt Ihr das mitgelieferte Applet benutzen. Wichtig: Vorher Cookies
im Browser aktivieren !!
-
Zum Debuggen könnt Ihr nach
System.err schreiben und dann im Verzeichnis
/var/log in der Datei httpd.error_log nachschauen (auf dem Rechner
quak). Die Strings solltet Ihr noch mit Eurer User-ID markieren, weil alle Servlets dort
reinschreiben, und dann am besten grep benutzen. Einige Exceptions der
WebSphere gehen auch in /opt/IBMWebAS/logs/servlet/servletservice/error_log.
Die Zusammenstellung dieser Programme und Dokumentationen sind urheberrechtlich geschützt.
© Copyright 1999-2000 Elias
Volanakis.
Alle Rechte vorbehalten.
Abgabe:
Als Abgabe werden funktionierende Versionen der .java Dateien der Servlets erwartet. Und ebenso die User-ID unter der Sie die Dateien abgelegt habt.
Abgabe bitte per Mail an Denis Reimann oder während der Anwesenheitszeit.
|
|
|