Ein eigenes Servlet
Lernen der Mechanismen
Nichts Kompliziertes, sondern einfaches Servlet, das
»Hello World« mit Datum und Uhrzeit ausgibt
Einige Vorarbeiten (einmalig):
Verzeichnisstruktur erstellen
Servlet schreiben
Servlet übersetzen
Klasse an die richtige Stelle kopieren
Deployment descriptor einrichten
Web−Anwendungen mit Java
101
Verzeichnisstruktur erstellen
Verzeichnisse unterhalb von webapps enthalten
Web−Anwendungen.
ROOT ist eine Web−Anwendung.
Jede Web−Anwendung benötigt das spezielle
Verzeichnis WEB−INF mit Metainformationen und
internen Daten der Web−Anwendung.
web.xml: Deployment descriptor
classes/de/rainer_klute/servlet/Hello.class: Servlet
Web−Anwendungen mit Java
102
Verzeichnisstruktur erstellen
Konfiguration in
conf/server.xml spezifisch für
Tomcat.
Dateisystemstruktur der Web−
Applikationen durch Servlet−
Spezifikation definiert.
Web−Anwendungen mit Java
Andere Server, andere
Konfigurationsmechanismen
103
Java−Quellen könnten auch
an anderem Ort stehen.
Servlet übersetzen
Für die Übersetzung müssen die Klassen des
Servlet−APIs im Classpath enthalten sein.
cd webapps/ROOT/WEB−INF/src/de/rainer_klute/servlet
javac −classpath
/opt/local/tomcat/common/lib/servlet.jar Hello.java
CLASSPATH="/opt/local/tomcat/common/lib/servlet.jar"
export CLASSPATH
javac Hello.java
Web−Anwendungen mit Java
104
Servlet übersetzen
Tomcat sucht Servlets im Verzeichnis
WEB−INF/classes der Web−Applikation.
mkdir −p [tomcat]/webapps/ROOT/WEB−
INF/classes/de/rainer_klute/servlet
mv Hello.class [tomcat]/webapps/ROOT/WEB−
INF/classes/de/rainer_klute/servlet
Klassendatei unmittelbar in WEB−INF/classes
generieren
cd webapps/ROOT/WEB−INF
mkdir classes
javac −classpath
/opt/local/tomcat/common/lib/servlet.jar −d classes
src/de/rainer_klute/servlet/Hello.java
Web−Anwendungen mit Java
105
Deployment descriptor erstellen
Datei WEB−INF/web.xml
Beschreibt Struktur und Eigenschaften einer
Web−Anwendung
XML−Datei
DTD (Document Type Definition) definiert die Syntax.
Idealerweise mit syntaxgesteuertem XML−Editor
bearbeiten
Emacs mit PSGML−Modus
Web−Anwendungen mit Java
106
Deployment descriptor erstellen
<?xml version="1.0" encoding="ISO−8859−1"?>
<!DOCTYPE web−app
PUBLIC "−//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web−app_2_2.dtd">
<web−app>
<!−− Macht Servlet dem Servlet−Container bekannt: −−>
<servlet>
<servlet−name>Hello</servlet−name>
<servlet−class>de.rainer_klute.servlet.Hello</servlet−class>
</servlet>
<!−− Ordnet das Servlet einem URL−Muster zu: −−>
<servlet−mapping>
<servlet−name>Hello</servlet−name>
<url−pattern>/Hello</url−pattern>
</servlet−mapping>
<servlet−mapping>
<servlet−name>Hello</servlet−name>
<url−pattern>/World</url−pattern>
</servlet−mapping>
</web−app>
Web−Anwendungen mit Java
107
Servlet testen
Tomcat neu starten
URI http://localhost:8080/Hello abrufen:
Web−Anwendungen mit Java
108
Servlets automatisch neu laden
Tomcat kann neue Versionen von Servlet−Klassen
erkennen.
Automatisches Laden einer neuen Servlet−Version
ohne Tomcat−Neustart
Sehr nützlich während der Entwicklung
Performance−Bremse in der Produktion, weil Tomcat
Änderungen überprüft
Voreinstellung: kein automatisches Laden
Web−Anwendungen mit Java
109
Servlets automatisch neu laden
In conf/server.xml ändern:
−−− server.xml.orig
Fri Mar 1 23:49:40 2002
+++ server.xml Sat Mar 9 19:07:05 2002
@@ −158,6 +158,10 @@
<!−− Define the default virtual host −−>
<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true">
+
+
+
+
<!−− Define the default configuration for
all contexts of this host. −−>
<DefaultContext reloadable="true"/>
<!−− Normally, users must authenticate themselves to each web app
individually. Uncomment the following entry if you would like
a user to be authenticated the first time they encounter a
Festlegungen gelten als Voreinstellungen für alle Web−
Applikationen desselben Hosts.
Bei Änderungen des Deployment descriptors
(WEB−INF/web.xml) Tomcat neu starten!
Web−Anwendungen mit Java
110
Manager−Applikation
Weitergehende Funktionen als Reload
Neue Web−Anwendung laden (»deployen«)
Beliebiger Context−Path
Beliebige Quelle (Verzeichnis oder WAR−Datei)
Web−Anwendungen neu laden
Web−Anwendungen und Anzahl der Sessions
anzeigen
Web−Anwendung entladen (»undeploy«)
Web−Anwendung anhalten, aber nicht entladen
Angehaltene Web−Anwendung neu starten
Web−Anwendungen mit Java
111
Manager−Applikation
Manager−Applikation nach
${CATALINA_BASE}/webapps kopieren
manager/WEB−INF/web.xml
Aktiviert Tomcat−interne Servlets
Benutzer mit Rolle »manager« eintragen
Beispielsweise bei MemoryRealm:
<tomcat−users>
<user name="tomcat"
<user name="role1"
<user name="both"
<user name="klute"
</tomcat−users>
password="tomcat"
password="tomcat"
password="tomcat"
password="geheim"
Web−Anwendungen mit Java
112
roles="tomcat, secret" />
roles="role1" />
roles="tomcat,role1" />
roles="manager" />
Manager−Applikation
Sehr rudimentäre Bedienung durch Eingabe
von URIs
http://mark.rainer−klute.de:8080/manager/reload?path=/auth
Alles weitere: Tomcat−Dokumentation lesen,
hier: Manager−HOWTO
Web−Anwendungen mit Java
113
Übungsaufgabe 3: Property−Servlet
Vor dem Erstellen »richtiger« Web−Anwendungen sind einige
Fingerübungen sehr hilfreich:
Richten Sie auf dem Übungsrechner unter Ihrer Benutzerkennung Ihre eigene
Tomcat−Umgebung ein!
Schreiben Sie ein Servlet, das die System−Properties (siehe Übungsaufgabe
2) alphabetisch sortiert ausgibt, idealerweise als HTML−Tabelle!
Web−Anwendungen mit Java
114
HTTP−Requests mit Parametern
Ziel: Verarbeiten von Benutzereingaben durch das
Servlet
Basis aller »echten« Web−Anwendungen
Übergabe von Parametern an Servlet im HTTP−
Request
Einfache Beispiele:
»Hello World«−Servlet soll Nutzer individueller
ansprechen: Übergabe eines Ortsnamens
Ortsname wird in Servlet−Ausgabe eingeblendet.
E−Shop: Von der Produktübersicht zu den
Detailinformationen verzweigen
Dynamische Zielangabe beschreibt Datenbankobjekt.
Web−Anwendungen mit Java
115
Parameterübergabemechanismen
Speziell geformte URLs
/Hello/Dortmund?Sprache=DE
/Hello?Ort=Dortmund&Sprache=DE
GET−Request
Web−Formulare
Übertragen der Formulardaten − meist als POST−
Request, manchmal als GET−Request (siehe oben)
Cookies
Sessions
ID im HTTP−Header
Mischformen
Web−Anwendungen mit Java
116
Snoop−Servlet
Snoop−Servlet: zeigt Servlet−Parameter und weitere
Informationen an.
Web−Anwendungen mit Java
117
Snoop−Servlet
Servlet−Mapping:
<servlet−mapping>
<servlet−name>Snoop</servlet−name>
<url−pattern>/Snoop/*</url−pattern>
</servlet−mapping>
Bildet alle URIs, die mit »/Snoop/« beginnen, auf das
Servlet namens »Snoop« ab.
Servlet analysiert den URI (siehe unten) und kann
entsprechende Aktionen durchführen.
Web−Anwendungen mit Java
118
Info−Methoden
Dreh− und Angelpunkt eines HTTP−Servlets:
Methode void service(ServletRequest,
ServletResponse)
Analysiert HTTP−Methode und leitet Request weiter an
doGet(...), doPost(...) usw.
HttpServletRequest
Unterklasse von ServletRequest
Besitzt Methoden zum Erfragen diverser Informationen,
insbesondere der Servlet−Parameter.
Web−Anwendungen mit Java
119
Request−Parameter abfragen
Einfache Abfrage fest definierter Parameter
Beispiel: /Hello?Ort=Dortmund
»?« leitet Parameter ein, »&« trennt Parameter.
Parametername: Ort
Parameterwert: Dortmund
public void doGet(HttpServletRequest request,
{
}
HttpServletResponse response)
throws ServletException, IOException
String ort = request.getParameter("Ort");
....
Web−Anwendungen mit Java
120
Beliebige Parameternamen
Im URI können beliebige Parameternamen stehen. Ein
Servlet kann sie erfragen:
/Hello?Ort=Dortmund&Schnism=Tr%FCst
»%FC«: im URL zulässige Ersatzdarstellung für »ü«
Im URL sind keine »Sonderzeichen« erlaubt.
Darstellung beliebiger Zeichen durch Hexadezimalwert
Enumeration e = request.getParameterNames();
while (e.hasMoreElements())
{
String name = (String) e.nextElement();
String values = request.getParameter(name);
...
}
Web−Anwendungen mit Java
121
Mehrfache Parameterwerte
Gleicher Parameter kann mehrfach mit
unterschiedlichen oder gleichen Werten vorkommen.
Beispiel:
/Hello?x=0&x=1&x=0
Enumeration e = request.getParameterNames();
while (e.hasMoreElements())
{
String name = (String) e.nextElement();
String[] values =
request.getParameterValues(name);
for (int i = 0; i < values.length; i++)
System.out.println(name + ": " +
values[i]);
}
Web−Anwendungen mit Java
122
Parameter−Map
Statt getParameterNames() und
getParameterValues() das Map−Interface nutzen.
Map p = request.getParameterMap();
Schlüssel sind von Typ String.
Werte sind vom Type String[].
Web−Anwendungen mit Java
123
Der Query−String
Beispiel−URI:
http://localhost:8080/Snoop/Hello/Foo?Bar&x=%FC
String getQueryString()
Ergebnis: Bar&x=%FC
Query−String: alles ab »?«
In URI ohne »?« ist der Query−String null.
In URI mit »?«, aber ohne Parameter hinter dem »?« ist
der Query−String leer.
Web−Anwendungen mit Java
124
Request−URI und Pfade
http://localhost:8080/Snoop/Hello/Foo?Bar&x=%FC
String getRequestURI()
Ergebnis: /Snoop/Hello/Foo
Request URI: alles bis zum »?«
»http://localhost:8080« steckt nicht im HTTP−
Request, sondern in der Art und Weise des
Verbindungsaufbaus.
String getServletPath()
Ergebnis: /Snoop
String getPathInfo()
Ergebnis: /Hello/Foo
Web−Anwendungen mit Java
125
Pfad zur Web−Anwendung
http://localhost:8080/Snoop/Hello/Foo?Bar&x=%FC
String getPathTranslated()
Ergebnis:
/home/klute/tomcat/webapps/ROOT/Hello/Foo
Pfad zur Web−Anwendung
Nur definiert, falls Pfadinformationen (siehe
getPathInfo()) vorhanden sind, sonst null. Ein
einzelner »/« reicht aus.
Web−Anwendungen mit Java
126
Weitere Info−Methoden des Requests
Vom Browser gesendete HTTP−Header
HTTP−Methode
Interessant, wenn Servlet die Methode service()
überschreibt.
Bei authentifizierten Zugriffen: Benutzername,
Authentifizierungsschema
Sitzungen: Session−ID, Session, Cookies, Principal,
Rolle
Servlet: Initialisierungsparameter, Konfiguration,
Kontext, Info, Name
Web−Anwendungen mit Java
127
Servlets: Ausblick
Bisher: Einführung in Servlet−Grundlagen, Tomcat als
Servlet−Container, einfache Servlets mit und ohne
Parametern sowie Deployment descriptor
Demnächst: Formulare, Sessions, HTTP−Response,
Sicherheit
Vorher aber: Java Server Pages (JSP)
HTML−Seiten mit eingebettetem Java−Quellcode
Kein »programmiertes HTML« mehr nötig:
out.println("<title>Hello World!</title>");
out.println("<h1>Hello World!</h1>");
Wesentlich einfacheres Vorgehen bei Änderungen
Automatische Übersetzung und Installation
Web−Anwendungen mit Java
128
Übungsaufgabe 5: Produktansichten
Schreiben Sie eine Web−Anwendung aus einem oder mehreren Servlets,
die die Produkte eines E−Shops präsentiert. Folgende Funktionalität wird
erwartet:
Die Eingangsseite zeigt einen Übersicht aller Produkte.
Aus der Übersicht gelangt man durch einen Klick zur Darstellung eines
einzelnen Produkts mit detaillierten Informationen, einem Bild (falls vorhanden)
und dem Preis.
Aus der Einzelsicht gelangt der Benutzer per Klick wieder zurück zur
Übersicht.
Die Pflege der Inhalte (Text, Bild, Preis und evtl. weitere) ist noch nicht
Gegenstand der Web−Anwendung. Überlegen Sie, wie Sie diese Daten
außerhalb der Web−Anwendung geeignet ablegen und pflegen können!
Überstürzen Sie nichts: Sie haben für diese Aufgabe fast zwei Wochen
Zeit, da die nächste Übungsaufgabe harmlos ist! Die folgenden
Aufgaben bauen auf dieser auf, so daß Sie sie ernstnehmen sollten.
Web−Anwendungen mit Java
129
Java Server Pages (Teil 1)
Java Server Pages
(Teil 1)
Web−Anwendungen mit Java
130
JSP im Überblick
Was ist eine JSP−Seite? Erste Antwort: eine
HTML−Seite mit integrierten Java−Anweisungen
Beispieldatei ROOT/Beispiel.jsp:
<!DOCTYPE html PUBLIC "−//W3C//DTD HTML 4.0//EN//">
<%@ page session="false" import="java.util.*" %>
<html>
<head>
<title>JSP−Beispiel</title>
</head>
<body style="background: #ffffff">
<h1>JSP−Beispielseite</h1>
JSP im Überblick
Anzeige im Browser:
Allgemein:
Schablone aus statischem Text (nicht nur HTML)
Integrierte Skripting−Anweisungen in Java (oder
im Prinzip anderen Sprachen)
Web−Anwendungen mit Java
132
Model View Controller (MVC)
Ziel: Trennung von Anwendungslogik und
Präsentation (Visualisierung)
Vorteile:
Klare Unterscheidung der unterschiedlichen
Aufgabenbereiche
Anwendungslogik und Präsentation werden voneinander
unabhängig.
Präsentation wird austauschbar.
Parallele Präsentationen werden möglich, z.B.
unterschiedliche Sprachen,
unterschiedliche Designs,
unterschiedliche Oberflächen (Web, Swing usw.).
Web−Anwendungen mit Java
133
Model View Controller (MVC)
Model
Controller
View
Das MVC−Prinzip ermöglicht die gewünschte
Trennung.
Model enthält Anwendungsdaten und −logik.
View präsentiert dem Benutzer die Daten und nimmt
Eingaben entgegen (Tastatur, Maus, Sprache usw.).
Mehrere Views sind möglich.
Controller vermittelt zwischen Model und Views.
Web−Anwendungen mit Java
134
MVC: Zustandsänderung des Models
Model
1
Controller
2
2
View 1
View 2
Änderung des Models muß sich in den Views
widerspiegeln.
Schritt 1: Model informiert Controller über
Zustandsänderung.
Schritt 2: Controller ändert View(s).
Web−Anwendungen mit Java
135
MVC: Änderung eines Views
2
Model
3
Controller
1
4
View 1
View 2
Benutzereingabe oder Änderung durch Controller
Schritt 1: View propagiert Änderung zum Controller.
Schritt 2: Controller modifiziert Model.
Schritt 3: Model informiert Controller (siehe oben).
Schritt 4: Controller ändert Views (siehe oben).
View sollte selbstbewirkte Model−Änderungen
ignorieren.
Web−Anwendungen mit Java
136
MVC mit JSP
JSP−Seite dient lediglich der Präsentation.
Einbetten von Anwendungsdaten in die HTML−Seite
Einfache Präsentationsanweisungen
Weiterleiten von Benutzereingaben an eine Controller−
Klasse
Anklicken von Links
Absenden von HTML−Formularen
Interaktion mit Java−Applets
Keine Anwendungslogik in der JSP−Seite!
Im wesentlichen Aufruf von get− und
set−Methoden der Controller−Klasse
Web−Anwendungen mit Java
137
Funktionsweise von JSP
JSP−Container
Web−Server
JSP−Servlet
Generierte
Servlets
Aus JSP−Seiten werden Servlets.
Steuerung durch JSP−Container
Servlet−Container plus JSP−Funktionalität
Andere Bezeichnung: Web−Container
Web−Anwendungen mit Java
138
JSP−Seiten
Dateien mit
Endung .jsp
Funktionsweise von JSP
Der JSP−Container
bemerkt Änderung an JSP−Seite und generiert daraus
die Servlet−Klasse neu
Java−Quellcode erzeugen
Java−Quellcode übersetzen,
führt Methode destroy() der alten Servlet−Instanz aus
und entlädt das Servlet,
lädt das neu generiertes Servlet und führt dessen
Methode init() aus.
Anschließend bearbeitet das neue Servlet ankommende
Requests mittels service().
Translation phase / Execution phase
Web−Anwendungen mit Java
139
Funktionsweise von JSP
JSP−Container
Web−Server
JSP−Servlet
Generierte
Servlets
Separate Übersetzung der JSP−Seiten
Keine Aktualitätsprüfungen zur Laufzeit
Bessere Performance in produktiven
Anwendungen
Web−Anwendungen mit Java
140
JSP−Seiten
JSP−Compiler
Funktionsweise von JSP
Eine JSP−Seite ist ein Servlet.
Lebenszyklus wie bei »normalen« Servlets:
init(), service(), destroy()
Diese Methoden stehen in der JSP−Seite nicht zur
Verfügung. Der JSP−Container generiert sie in das Servlet
hinein.
In der JSP−Seite kann man vergleichbare Methoden
definieren:
void jspInit() wird vor dem ersten Ausführen der
JSP−Seite ausgeführt.
void jspDestroy() wird vor dem Entladen
der JSP−Seite ausgeführt.
Web−Anwendungen mit Java
141
Tomcat und JSP
In Tomcat erledigt das JSP−Servlet Jasper die nötigen
Aufgaben.
Zuordnung von URI zu JSP−Seite bzw. dem
generierten Servlet implizit durch Endung ».jsp«
Zeitstempel von JSP−Seiten und generierten Servlets
vergleichen und bei Bedarf
Java−Quellcode generieren,
Java−Quellcode übersetzen,
alte Servlet−Version durch neue ersetzen.
Voreingestellte Konfiguration: keine
Aktualitätsprüfung zur Laufzeit
Web−Anwendungen mit Java
142
JSP−Skripting
Deklarationen
Variablen, Methoden usw.
<%! int i; %>
Skriptlets
Java−Anweisungen
Werden unverändert in das generierte Servlet eingefügt.
Ausgaben auf den JspWriter out nur explizit
<% i = i + 1; out.println(i); %>
Ausdrücke
Werden ausgewertet und nach out ausgegeben
<%= i + 27 %>
Web−Anwendungen mit Java
143
JSP−Skripting
Kommentare
Erscheinen nur in der JSP−Seite, aber weder im
generierten Servlet noch in der HTML−Ausgabe.
<%−− Dies ist ein JSP−Kommentar. −−%>
<% /* Dies auch (für Java). */ %>
HTML−Kommentare
<!−− Kommentar −−>
Haben mit JSP nichts zu tun.
Erscheinen in der HTML−Ausgabe
Per JSP modifizierbar:
<!−− Kommentar mit <%= ... %> Einfügung −−>
Web−Anwendungen mit Java
144
JSP−Skripting
Ersatzdarstellungen
Im Skript: %> → %\>
In der Schablone: <% → <\%
In Attributen:
’ → \’ (In Attributen attr=’value’)
" → \" (In Attributen attr="value")
\ → \\
%> → \%\>
<% → <\%
’ → &apos;
" → &quot;
Web−Anwendungen mit Java
145
JSP−Skripting: Beispiel
Szenario:
Kunde hat im E−Shop eingekauft.
Anzeige des neuen Kontostands nach dem Einkauf
Web−Anwendungen mit Java
146
JSP−Skripting: Beispiel
<!doctype html public "−//W3C//DTD HTML 4.0//EN//">
<html>
<head>
<title>Ihr Kontostand</title>
</head>
<body style="background: #ffffff">
<h1>Ihr Kontostand</h1>
<%−− JSP−Kommentar: wird nicht in generiertes
Servlet eingefügt. −−%>
<!−− HTML−Kommentar: wird in generiertes Servlet
eingefügt. −−>
<%! float kaufsumme = 123.46f;
float saldoAlt = 100.00f;
float saldoNeu;
%>
Web−Anwendungen mit Java
147
Skripting−Elemente: Beispiel
<table border="1">
<tr>
<td>Alter Saldo:</td>
<td><%= saldoAlt %> EUR</td>
</tr>
<tr>
<td>Kaufsumme:</td>
<td><%= kaufsumme %> EUR</td>
</tr>
<% saldoNeu = saldoAlt − kaufsumme; %>
<tr>
<td>Neuer Saldo:</td>
<
<td><%= format(saldoNeu) %> EUR</td>
</tr>
</table>
Web−Anwendungen mit Java
148
Skripting−Elemente: Beispiel
<%! String format(float f)
{
String s = Float.toString(f);
return f >= 0 ? s :
"<span style=’color: red’>" + s + "</span>";
}
%>
<p>
<% if (saldoNeu >= 0) { %>
Sie haben ein Guthaben von <%= saldoNeu %> EUR.
<% } else { %>
Ihr Konto ist um <%= −saldoNeu %> EUR
überzogen.
<% } %>
</p>
</body>
</html>
Web−Anwendungen mit Java
149
Generierter Java−Quellcode
import
import
import
import
import
import
import
import
import
import
import
import
javax.servlet.*;
javax.servlet.http.*;
javax.servlet.jsp.*;
javax.servlet.jsp.tagext.*;
java.io.PrintWriter;
java.io.IOException;
java.io.FileInputStream;
java.io.ObjectInputStream;
java.util.Vector;
org.apache.jasper.runtime.*;
java.beans.*;
org.apache.jasper.JasperException;
public class _0002fKontostand_0002ejspKontostand_jsp_0
extends HttpJspBase {
Web−Anwendungen mit Java
150