About Me About MeProjects ProjectsPhotos PhotosSitemap Sitemap
  About Me > C/S Praktikum 99: Servlets > Aufgaben, Blatt 7

 

C/S Praktikum 1999-2000

Blatt 7: Servlets, Teil I

Zweck der zwei Aufgaben, die weiter unten vorgestellt werden, ist, daß Ihr erste Erfahrungen mit der Programmierung von Servlets und JSPs (JavaServerPages) sammelt. In den folgenden Paragraphen findet Ihr das nötige technische Hintergrundwissen für die Programmierung der Aufgaben.

Eine allgemeine (nicht technische) Einführung zum Thema Servlets findet Ihr hier.

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 Klient (Webbrowser) braucht Java nicht zu unterstützen. Eine Bespielanwendung für Servlets ist die Anbindung eines Servers an eine Datenbank.

Zur Kommunikation zwischen Servlet und Server ist eine plattformunabhängige Schnittstelle definiert, das Java Servlet API. Ein einmal programmiertes Servlet kann also prinzipiell auf jedem Server laufen, der dieses API unterstützt.

Das Java Servlet API besteht aus folgenden Packages:

  • Package javax.servlet: Enthält Klassen für die Implementierung von generischen (protokollunabhängigen) Servlets.
  • Package javax.servlet.http: Enthält Klassen für die Implementierung von Servlets, welche das HTTP Protokoll benutzen (HttpServlets).

HttpServlets

Kurzeinführung ins HTTP Protokoll: Das HTTP Protokoll ist ein einfaches, verbindungsloses Protokoll. Verbindungslos heißt, daß zwischen Klient (Webbrowser) und Server keine permanente Verbindung besteht, sondern nur eine temporäre.

Wenn der Klient 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 von dem Server zu bekommen und das POST Kommando dazu Daten an der Server zu senden.

HttpServlets erstellen: Ein HttpServlet erhält man in dem man die Klasse HttpServlet aus dem Package javax.servlet.http erweitert. Ein HttpServlet erhält requests von einem Webserver und schickt responses zurück. Die wichtigsten Methoden dieser Klasse sind:

  • doGet(HttpServletRequest, HttpServletResponse): um GET requests zu verarbeiten
  • doPost(HttpServletRequest, HttpServletResponse): um POST requests zu verarbeiten (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 hinprogrammieren (z.B. Daten die sich während der Laufzeit nicht ändern aus einer Datenbank holen).
  • destroy: Wird einmal aufgerufen wenn das Servlet vom Server aus dem Speicher entfernt wird. Wenn notwendig, kann man hier Befehle zum Aufräumen programmieren.

Hinweis: In den Aufgaben werdet Ihr nur doGet bzw. doPost benötigen.

Wichtig ist zu wissen das jedes Servlet Objekt vom Server nur einmal erzeugt (instanziiert) 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. Variablen die nur innerhalb von doGet/doPost Methoden existieren sind davon nicht betroffen.

HTTP-Servlet handling GET and POST requests

Java Server Pages (JSPs)

Der Applikationsserver den wir benutzen unterstützt außerdem das Java Server Pages API.

JSPs sind "normale" HTML Seiten welche zusätzlich eingebetete Java Befehle enthalten. Wenn ein JSP Aufgerufen wird, erstellt der Server automatisch ein Servlet aus dem JSP, so daß der HTML Code aus dem JSP und die Java Befehle zusammen ausgeführt werden. Für den Benutzer ist dies absolut transparent.

Durch JSPs wird es möglich die Applikationslogik von der Präsentation der Daten zu trennen. Dies passiert indem man die Applikationslogik in den Servlets programmiert und diese die erzeugten Daten an JSPs schicken, welche die Anzeige der Daten übernehmen.

JSP Access Sample
[Aufruf eines JSPs durch ein Servlet]

JSPs erstellen

Eine JSP Datei muß mit .jsp enden. Zusätzlich zu HTML Tags können JSP Tags benutzt werden. Die wichtigsten JSP Tags sind:

<%@ und %> Tags (sog. JSP Directives): Dieser Tag wird verwendet um zu spezifizieren welche Skriptsprache benutzt wird, welche Interfaces implementiert werden (doGet oder doPost), welche Java Klassen importiert werden und anderes.

Der Syntax dieses Tags ist <%@ directive_name = "value" %>

Die wichtigsten Werte für directive_name sind:

  • language - Spezifiziert welche Skriptsprache in diesem JSP benutzt wird. Zur Zeit wird nur der Wert "java" unterstützt.
  • method - Definiert in welche Methode der im JSP enthaltene Code geschrieben werden soll. Der Standardwert ist "service". Andere Werte sind "doGet" bzw. "doPost".
  • import - Gibt an welche Klassen durch das JSP importiert werden sollen. Diese Direktive kann mehr als einmal benutzt werden, um mehrere Packages zu laden.

Beispiel:
<%@ language = "java" %>
<%@ method = "doGet" %>
<%@ import = "java.util.*" %>
<%@ import = "java.sql.*" %>

<script runat=server> und <script> Tags: Innerhalb dieser Tags können klassenweite Methoden und Variablen definiert werden (in normalem Java-Code). Diese können dann innerhalb des ganzen JSPs aufgerufen werden. Der Ausdruck runat=server darf nicht weggelassen oder geändert werden!

Beispiel:
<script runat=server>
    private static int counter = 0;
    private GregorianCalendar myGC = new GregorianCalendar();
    private String runSince = myGC.get(Calendar.DATE);

    private String since() { return runSince; }
    private void resetCount() { counter = 0; }
</script>

<% und %> Tags (Inline Java Code, sog. "Scriptlets"): Zwischen diesen Tags kann normaler Java Code geschrieben werden, welcher an dieser Stelle ausgeführt wird. Es wird kein direkter Output in die HTML Seite geschrieben!

Folgende vier Variablen sind vordefiniert: request (vom Typ HttpServletRequest), response (vom Typ HttpSevletResponse), out (vom Typ PrintWriter) und in (vom Typ BufferedReader). Außerdem kann man alle Variablen und Methoden benutzen, die innerhalb des Skript Tags definiert wurden.

Beispiel:
    <% resetCount(); %>
    <% out.println("Hello World"); %>

<%= und %> Tags: Mit diesen Tags kann der Output aus Java Variablen und Methoden in die HTML Seite eingefügt werden. Primitive Typen wie int und float werden automatisch nach String konvertiert.

Beispiele:
    <%= (counter++) %>
    <%= since() %>

<bean> und <bean> Tag: Mit diesen Tags kann auf JavaBeans zugegriffen werden, die z.B. vorher in die Request geschrieben worden sind. Ein Bean kann jede Java-Klasse sein, die das Interface serializable implementiert und über get_xxx und set_xxx Methoden verfügt.

Der Syntax dieses Tags ist:
<bean name="Bean_name" varname="local_Bean_name"
    type="class_or_interface_name" introspect="yes|no"
    beanName="ser_filename" create="yes|no"
    scope="request|session|userprofile"
    <param property_name="value"
</bean>

  • name - Der Variablenname unter dem das Bean im definierten Scope abgelegt ist/wird.
  • varname - Dieses Attribut ist optional. Hier kann ein Name definiert werden, unter dem das Bean im JSP bekannt sein soll (sonst wird name Benutzt).
  • type - Der Klassenname des Bean (inkl. Package-Name). Von diesem Typ wird das Bean im generierten Java Code sein.
  • introspect - Wenn dies den Wert "yes" hat, wird der JSP Preprozessor alle Properties des Request-Objekts untersuchen und die set_xxx Methoden des Beans (aus BeanInfo) aufrufen, die den gleichen Namen haben. Der Standardwert ist "yes".
  • create - Ist der Wert auf "yes" gesetzt, wird der JSP Preprozessor eine Instanz des Beans erzeugen, falls er das Bean nicht im spezifizierten Scope findet. Der Standardwert ist "yes".
  • beanName - Der .class-Datei Name, der Package Name des Beans oder der Name des .ser-Files (serialized file) welches das Bean Enthält. Dieses Attribut wird nur benutzt wenn create="yes" gesetzt ist und das Bean nicht im Kontext des spezifizierten Scope existiert.
  • scope - Spezifiziert wo das Bean abgelegt ist bzw. wie lange es existieren soll. Der Standardwert ist "request". Die wichtigsten Werte sind:
    • request - Das Bean ist im Kontext der Request abgelegt. In der Regel wurde dies von dem Servlet, welches diese Seite aufrief, veranlasst. Falls das Bean nicht im Kontext der Request existiert und create="yes" gesetzt ist, wird es in diesem Kontext erzeugt.
    • session - Das Bean existiert im Kontext der Session (dazu mehr im Teil II). Falls das Bean nicht in diesem Kontext existiert und create="yes" gesetzt ist, wird es in diesem Kontext erzeugt.
  • param - Eine optionale Liste von (Bean)Properties und Werten. Diese Werte werden automatisch, durch Introspection, im Bean gesetzt, wenn dieses Bean instanziiert wird.

<repeat> und </repeat> Tags: Mit diesen Tags kann ein Block aus HTML und JSP Code mehrfach ausgeführt werden. Die Schleife wird solange durchlaufen bis der Wert ending_index erreicht wird, oder eine ArrayIndexOutOfBounds Exception geschmissen wird. Falls dies in der Mitte der Schleife passiert, werden in der Regel unvollständige HTML Tags generiert! Die Exception sollte also am besten am Anfang des <repeat>-Tags auftauchen.

Der Syntax dieser Tags ist:
<repeat index=name start=starting_index end=ending_index>

</repeat>

wobei mit:

  • index=name - der Name der Schleifenvariable definiert wird
  • start=starting_index - der Startwert der Schleifenvariable gesetzt wird. Der Standardwert ist 0.
  • end=ending_index - der Endwert der Schleifenvariable gesetzt wird. Wenn der Tag weggelassen wird, wird als Endwert der Maximalwert genommen. Dieser ist 2.147.483.647.

Beispiel:
<repeat index=idx start=0 end=5>
    <%= idx %><br>
</repeat>

Bevor Ihr beginnt:

Im Praktikum benutzen wir Apache als Webserver gekoppelt mit dem WebSphere Applikationsserver von IBM, welcher die Servlets/JSPs ausführt. Angebunden ist eine SQL-Datenbank (DB2) in der die Produkte eines Pizza-Lieferdienstes abgelegt sind. Im Rahmen der Aufgaben werdet Ihr einige Produktbeschreibungen aus der Datenbank holen. Um dies so einfach wie möglich zu machen gibt es eine Package namens pizzasvc.db, welche Klassen enthält, die die Datenbank auf Objekte abbilden. Mehr dazu in der Aufgabenstellung.

3-Tier Modell (Client, Web/App-Server, DB)
[Das 3 Schichten Modell]

Braucht man extra Klassen ? (Ja)

 Da die Servlets das Java Servlets API benutzen braucht Ihr die entsprechenden .JAR Dateien. Diese findet Ihr auf dem AFS unter /home/volanaki/praktikum/classes.zip. Die Datei enthält auch das Package pizzasvc.db. Ihr solltet ein Verzeichnis in eurem Account erstellen und die .zip-Datei dort entpacken.

Dann müßt Ihr noch die CLASSPATH Variable auf die .JAR-files setzen. Im Beispiel befinden sich die Dateien im Verzeichnis "myClasses". Der Befehl muß natürlich in eine Zeile geschrieben werden. Falls die Fehlermeldung "CLASSPATH: Undefined variable." kommt, den Befehl setenv CLASSPATH eingeben und es nochmal versuchen.

setenv CLASSPATH {$CLASSPATH}:
/home/volanaki/myClasses/ibmwebas.jar:
/home/volanaki/myClasses/jst.jar:
/home/volanaki/myClasses/jsdk.jar:
/home/volanaki/myClasses/xml4j.jar:
/home/volanaki/myClasses/databeans.jar:
/home/volanaki/myClasses/

Gibt es Rahmenprogramme? (Ja)

Ja, die Rahmenprogramme findet ihr (html)hier.

Welches JDK kann benutzt werden?

Ihr solltet das Blackdown JDK 1.1.7 für Linux benutzen. Dies gibt es auf den Rechnern helga und sunshower (informatik.uni-tuebingen.de).

Wo muß man die Lösungen ablegen damit der Server sie findet?

  • Die .class-Files Eurer Servlets legt ihr auf helga, in das Verzeichnis /usr/opt/IBMWebAS/servlets/aufgaben/user_id, wobei user_id Eure login ID ist.
  • Eure Servlets müssen dem Package aufgaben.user_id gehören, sonst findet der Server sie nicht!
  • Eure .html und .jsp Dateien legt Ihr in das Verzeichnis /home/volanaki/public_html/user_id

Wie kann die html-Dateien/JSPs/Servlets aufrufen?

  • Damit das ganze Funktioniert müßt Ihr eine HTML-Einstiegsseite in das html Verzeichnis legen und diese mit: http://helga.informatik.uni-tuebingen.de/~volanaki/user_id/htmlSeite aufrufen.
  • Von der Einstiegsseite aus und in den folgenden Seiten/Servlets könnt Ihr dann den relativen Pfad /~volanaki/user_id/Seite benutzen, um .JSP und .HTML Seiten aufzurufen
  • Um Servlets von der Einstiegsseite aufzurufen müßt Ihr den Pfad: /servlet/aufgaben/user_id/dateiname (ohne .class) benutzen.

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:

  1. Die Datei Aufg1.html so anpassen, daß Euer Servlet aufgerufen wird und diese in daß public_html Verzeichnis legen, wie oben beschrieben.
  2. Nun könnt Ihr mit der Programmierung des Servlets fortfahren. Hier sind folgende Schritte notwendig:
    • Den Wert auslesen. Den Namen erfährt 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 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.
  3. 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 erstmal 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 der Package pizzasvc.db nach. Links sind unten angegeben.

Aufgabe 2

Wie Ihr in der vorherigen Aufgabe wahrscheinlich gemerkt habt, ist die Generierung von HTML-Code im Servlet recht umständlich. Deshalb wollen wir nun eine JSP zur Anzeige der Daten benutzen.

Folgende Schritte sind notwendig:

  1. Modifiziert die Datei Aufg2.html um Euer Servlet aufzurufen.
  2. Modifiziert das Rahmenprogramm Aufg2Servlet.java, so daß es die Produktliste, als Bean, einer JSP zur Verfügung stellt und diese dann aufruft. Den Code für die Datenbankabfrage könnt Ihr aus der ersten Aufgabe übernehmen.
  3. Modifiziert dann die Rahmendatei Aufg2.jsp, so daß die Daten aus dem Servlet in einer HTML Tabelle angezeigt werden. Außerdem schreibt innerhalb des <script>-Teils eine Methode welche double Variablen in Strings konvertiert, welche im deutschen Format sind (mit Komma statt Punkt und zwei Nachkommastellen), damit die Preise aus der Produktliste schön angezeigt werden. (Tip: Package java.text.*)
  4. Legt daß Servlet im Servletverzeichnis ab und die beiden anderen Dateien im .html Verzeichnis. Zum testen die .html-Datei aufrufen.

Tips:

  • Das JSP-File muß nicht kompiliert werden. Dies macht der Applikationsserver automatisch wenn das JSP durch den WebServer aufgerufen wird. Ihr müßt dazu das JSP in dem vorgesehenen Verzeichnis ablegen.
  • Falls Fehler während der Kompilierung/Ablauf des JSP auftauchen bekommt Ihr eine Webseite mit der Fehlermeldung bzw. Stacktrace zu sehen. Die Fehlermeldungen sind nicht immer hilfreich, aber Ihr solltet Euch dann nochmal Eure JSP sehr genau anschauen. Meist liegt es an einer Kleinigkeit.
  • Nicht vergessen, daß die JSP Datei mit .jsp enden muß.
  • Schaut die Dokumentation zu den Klassen com.sun.server.http.HttpServiceRequest und com.sun.server.http.HttpServiceResponse an. Falls Ihr konkrete Sachen über JSPs wissen woll schaut im .pdf File nach. Links sind unten angegeben.

Hinweise

Bearbeitungszeitraum: Die Woche vom 10.1 bis 16.1

Abgabe: Die .java Dateien der Servlets per Mail an <volanaki ÄT informatik.uni-tuebingen.de> schicken. Außerdem einen Hinweis hinzufügen, unter welcher User ID Ihr die JSP Datei abgelegt habt.

Betreuung: Der geplante Termin am Donnerstag, den 13.1 von 9-11 Uhr im Raum 023 (TI-Pool) auf dem Sand muß wegen Krankheit leider ausfallen. Es wird einen Ersatztermin am Montag, den 17.1 zur gleichen Zeit am gleichen Ort geben. Falls Probleme auftauchen könnt Ihr mir natürlich auch eine Mail schicken.

Links auf Dokumentation:

Nützliche technische Dokumentation:

(html)Servlet und JSP API
(html)com.sun.server.http.HttpService{Request,Response} API
(html)Java 1.1.x API
(html)Package pizzasvc.db - JavaDocs

Falls Ihr noch mehr Informationen über Servlet/JSP Programmierung benötigt, ist folgendes Dokument sehr zu empfehlen:

(html)WebSphere Application Server Guide, v. 1.0:
- Kapitel 3, Servlet Programmierung
- Kapitel 6, JSP Programmierung