Servlets - Praktische Informatik

Werbung
Servlets
Marc Monecke
[email protected]
Praktische Informatik
Fachbereich Elektrotechnik und Informatik
Universität Siegen, D-57068 Siegen
16. Juni 2003
Zusammenfassung
Neben statischem HTML-Text werden in Web-Seiten oft auch dynamische Inhalte angezeigt. Solche Inhalte werden von Programmen erzeugt, die an den HTTP-Server angebunden sind. Das Servlet-API ist eine Programmierschnittstelle, mit der Java-Programme
(Servlets) auf diese Weise verwendet werden können. Die Servlets werden in einem Servlet Container verwaltet, der für die Weiterleitung der Anfragen und die Rückgabe des
Ergebnisses zuständig ist.
Inhaltsverzeichnis
1 Einleitung und Motivation
1.1 CGI-Programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1
2 Servlets
2.1 Aufgaben eines Servlets . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Vorteile gegenüber CGI . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
3
3
3 Klassenhierarchie
3.1 Servlet-Container . . . .
3.2 Einfaches HTTP-Servlet
3.3 Web-Anwendungen . . .
3.4 Aufruf eines Servlets . .
3.5 Servlet Context . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
4
5
5
6
6
4 Servlet-Lebenszyklus
4.1 Initialisierung . . . . . . . . . . .
4.1.1 Initialisierungsparameter .
4.2 Ausführung . . . . . . . . . . . .
4.3 Zerstörung . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
6
7
7
8
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
i
5 Parameter
5.1 Parameter an Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.1 Verarbeitung im Servlet . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Verarbeitung von Formularen . . . . . . . . . . . . . . . . . . . . . . . . .
8
8
8
9
6 Sitzungen
6.1 Sitzungen mit Servlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
10
7 Zusammenfassung
10
ii
1
Einleitung und Motivation
– in Web-Anwendungen wird die Benutzungsschnittstelle durch Web Browser realisiert
– Darstellung, Layout
– Interaktion
– ein HTTP-Server liefert die Daten (HTML-Seiten) auf Anfrage
– oft werden neben statischem HTML-Text auch dynamische Inhalte benötigt:
– Inhalt basiert auf Daten, die der Benutzer eingegeben hat – etwa einer Suchanfrage
– Inhalt wird von Daten abgeleitet, die sich häufig ändern – etwa der Wetterbericht
– Inhalt enthält Daten, die von Datenbanken oder Fremdsystemen geliefert werden
– allgemein sind serverseitige Programme nötig, die die Daten ermitteln, erzeugen
oder aufbereiten
– Programme müssen an den HTTP-Server angebunden werden – weil der die Schnittstelle zum Klienten (dem Browser) bereitstellt
1.1
CGI-Programme
– Lösung: Common Gateway Interface (CGI) – Abbildung 1
CGI
Web Browser
HTTP−Server
CGI bin
HTTP
DB−Schnittstelle
DB
Abbildung 1: Anbindung von Programmen an den HTTP-Server über CGI
– Der Aufruf eines angebundenen CGI-Programms (CGI binary, CGI bin) läuft wie folgt
ab:
1. Der Browser nutzt das HTTP-Protokoll, um Anfragen an den HTTP-Server zu
schicken. Eine Anfrage besteht aus der Adresse des ausführbaren CGI-Programms
(eine URL) und optionalen Parametern.
2. Der HTTP-Server startet für jede Anfragen einen neuen (schwergewichtigen) Prozeß, der das CGI-Programm ausführt und übergibt die Parameter.
3. Das CGI-Programm erzeugt das Ergebnis, etwa indem es Daten aus einer Datenbank
ausliest, und liefert es in Form einer HTML-Ausgabe an den HTTP-Server zurück.
4. Der HTTP-Server schickt das Ergebnis an den Browser weiter.
1
– Beispiel: http://pi.informatik.uni-siegen.de/cw-bin/dbs-I.cgi
Hier wird eine SQL-Anfrage im Browser eingegeben und an ein Perl-Skript weitergeleitet, das die Anfrage auf einer Datenbank ausführt und das Ergebnis als Tabelle
zurückliefert.
Vorteile von CGI
– HTTP-Server und Anwendungsprogramm klar getrennt
– einfache, standardisierte Schnittstelle – dadurch ist das CGI-Programm weitgehend
unabhängig vom verwendeten HTTP-Server
– CGI-Programm kann in beliebiger Sprache geschrieben werden – häufig werden C
und Perl verwendet. Hier stehen auch zahlreiche Bibliotheken mit Hilfsfunktionen zur
Verfügung, die z.B. das Auslesen der Parameter und das Aufbereiten des Ergebnisses
erleichtern.
Nachteile von CGI
– für jede Anfrage wird ein neuer Prozeß erzeugt → hoher initialer Aufwand bei jedem
Zugriff
– bei vielen parallelen Anfragen entsteht eine große Zahl von Prozessen → hoher Verwaltungsaufwand
– Ressourcen (z.B. Datenbankverbindung) können nicht gemeinsam genutzt werden, da
das CGI-Programm nach Bearbeitung der Anfrage nicht weiter existiert
→ besser ein Serverprozeß, der Anfragen entgegennimmt und Ressourcen verwaltet
2
Servlets
– in Java geschriebene Programme
– werden auf dem Server innerhalb eines Servlet-Containers ausgeführt (Abbildung 2)
– Servlet-Container mit Verbindung zum HTTP-Server oder als Teil davon – das hängt
vom verwendeten HTTP-Server, dem verwendeten Servlet-Container und der Konfiguration ab. Servlet-Container können auch allein (stand-alone) verwendet werden und
übernehmen dann auch die Aufgaben eines einfachen HTTP-Servers. Ein solcher Betrieb ist besonders während der Entwicklung von Servlets sinnvoll.
Servlet Container
Web Browser
HTTP−Server
Servlet
HTTP
Abbildung 2: Servlets
2
2.1
Aufgaben eines Servlets
Servlets übernehmen die gleichen Aufgaben wie traditionelle CGI-Programme. Allerdings können sie aufgrund der umfangreichen Servlet-Schnittstelle und den vom ServletContainer angebotenen Diensten meist komfortabler und schneller entwickelt werden.
1. Daten vom Klienten (Browser) einlesen (Anfrage, Request)
2. weitere Informationen über Anfrage ermitteln – z.B. Hostname, Browser, Cookies
3. auf Basis der empfangenen Daten und der ermittelten Informationen Ausgabedaten
erzeugen – das Ergebnis kann direkt berechnet werden oder es können Informationen
aus einer Datenbank oder von einem Fremdsystem angefordert werden
4. Ausgabedaten in Antwort (Response) gemäß HTTP verpacken – z.B. Angabe des
Typs der übertragenen Daten (MIME header)
5. Senden des Ergebnisdokuments an den Klienten
2.2
Vorteile gegenüber CGI
– Effizienz: alle Servlets werden in einer Java VM ausgeführt, diese wird zusammen
mit dem HTTP-Server nur einmal gestartet. Jedes Servlet wird in einem thread ausgeführt – also unabhängig von den anderen Servlets, aber trotzdem mit nur geringem
Verwaltungsaufwand. Die zugehörige Java-Klasse eines Servlets muß nur einmal in den
Hauptspeicher geladen werden, auch wenn mehrere Instanzen davon existieren. Auch
können mehrere Servlets oder mehrere Instanzen eines Servlets gemeinsame Ressourcen
wie Datenbank-Verbindungen nutzen.
– Einfache Benutzung: Entwickler müssen keine weitere Sprache neben Java beherrschen, um mit Servlets arbeiten zu können. Im Servlet-API sind Dienste vorgeschrieben, die die Verwendung des HTTP-Protokolls unterstützen. Die nötigen Funktionen
sind also in den jeweiligen Implementierungen des API enthalten und müssen nicht in
Zusatzbibliotheken bereitgestellt werden.
– Portabilität: Java-Programme laufen auf jeder Plattform; Servlets können mit jedem Web-Server genutzt werden, der die standardisierte Servlet-Schnittstelle unterstützt
– Sicherheit: Servlet-Container enthält Sicherheitsmechanismen während CGI-Programme direkt in der Betriebssystem-Umgebung ausgeführt werden – CGI-Entwickler
müssen diese Mechanismen also selbst bereitstellen, etwa um den Zugriff auf Dateien
einzuschränken oder den Aufruf eines CGI-Programms nur bestimmten Benutzern zu
erlauben.
3
Klassenhierarchie
Abbildung 3 zeigt einige Klassen und Schnittstellen, die bei der Arbeit mit Servlets relevant sind.
– Schnittstelle Servlet: Die Operationen dieser Schnittstelle müssen alle Servlets implementieren:
– init führt die Initialisierung des Servlets durch den Servlet-Container
– in der service-Operation werden die Anfragen von Klienten bearbeitet
3
<<interface>>
ServletConfig
<<interface>>
Servlet
init()
getServletName()
getInitParameter()
getServletContext()
service()
destroy()
GenericServlet
service()
getServletConfig()
HttpServlet
init()
init()
destroy()
doGet()
doPost()
doPut()
Abbildung 3: Ausschnitt aus der Klassenhierarchie
– destroy wird aufgerufen, wenn das Servlet nicht mehr gebraucht wird – sie kann
also dazu genutzt werden, belegte Ressourcen freizugeben und temporäre Daten zu
löschen. Die destroy-Operation sollte allerdings nicht dazu genutzt werden, Daten
wie den Sitzungszustand oder statistische Daten zu sichern, da sie nicht in allen
Fällen aufgerufen werden muß – etwa, wenn ein Systemfehler auftritt.
– Schnittstelle ServletConfig: Objekte mit dieser Schnittstelle werden vom ServletContainer bei der Initialisierung erzeugt. Die Schnittstelle enthält z.B. die Operationen:
– getServletName liefert den Namen des Servlets zurück
– getInitParameter erlaubt den Zugriff auf Initialisierungsparameter, die bei der
Installation des Servlets im Container definiert werden können. Sie erlauben es, das
Servlet für die gegebene Aufgabe zu konfigurieren.
– getServletContext liefert ein ServletContext-Objekt zurück, das zur Kommunikation zwischen Servlet-Container und Servlet dient (genauer: ein Objekt, dessen
Klasse die Schnittstelle ServletContext implementiert). Es kann auch verwendet
werden, um globale Informationen zu speichern (s. Abschnitt 3.5).
– GenericServlet: Basisklasse für Servlets. Anfragen eines Klienten werden an die Operation service weitergeleitet.
– HttpServlet: Basisklasse für Servlets, die das HTTP-Protokoll unterstützen, und
meist Ausgangspunkt für die Entwicklung eigener Servlets. Anfragen des Klienten werden hier gleich auf die passenden Operationen doGet, doPost, doPut usw. abgebildet.
3.1
Servlet-Container
– verwaltet Servlets
– bietet Schnittstelle zur Kommunikation zwischen Servlet und Container
– kann Dienste für Verteilung, Sicherheit anbieten
– Beispiel: Tomcat aus dem Apache Jakarta-Projekt
– implementiert Servlet- und Java ServerPages-API
4
– kann allein genutzt werden oder integriert in Apache Web-Server
3.2
Einfaches HTTP-Servlet
import javax.servlet.*;
import javax.servlet.http.*;
public class Hello extends HttpServlet
{
String title = "STII Demo Servlet";
public void doGet ( HttpServletRequest
request,
HttpServletResponse response )
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><head>");
out.println("<title>" + title + "</title>");
out.println("</head><body>");
out.println("<h1>" + title + "</h1>");
out.println("<b>sehr einfaches Servlet</b>");
out.println("</body></html>");
}
}
– Antwort auf get-Anfragen: doGet
– Informationen über die Anfrage in HttpServletRequest enthalten
– Ergebnis in HttpServletResponse zurückliefern
– Typ des Ergebnisses mit setContentType() angegeben – dabei wird der MIMETyp (Multipurpose Internet Mail Extensions) angegeben, im Beispiel text/html
für HTML; bei Bildern z.B. image/gif und bei PDF-Dateien application/pdf.
– Ausgaben mit println in Ausgabestrom schreiben
→ response.getWriter()
3.3
Web-Anwendungen
– Servlets sind Teil einer Web-Anwendung, enthält
– Servlets
– JSP-Seiten
– JavaBeans und ’einfache’ Java-Klassen
– weitere Ressourcen wie HTML-Texte, Bilder
– Web-Anwendung wird im HTTP-Server/Servlet-Container installiert – eine installierte Web-Anwendung wird automatisch mit dem Servlet-Container gestartet und kann
über eine URL aufgerufen werden. Bei der Installation kann die Anwendung auch
konfiguriert werden, indem Initialisierungsparameter für die Servlets angegeben oder
Benutzer und Zugriffsrechte eingerichtet werden.
5
– Servlet-Container enthält Administrations-/Management-Werkzeuge zum Starten, Stoppen, Neuladen von Web-Anwendungen
– Auslieferung in Web-Archivdatei (.war): zip-Archiv mit Manifest-Datei
– zur Laufzeit: Web-Anwendung definiert Servlet Context
3.4
Aufruf eines Servlets
– URL zum Aufruf von Servlets: http://hostname/servlet/servlet-name
in diesem Fall liegen alle Servlets in einem gemeinsamen ’Namensraum’. Dies ist
möglich, weil der Servlet-Container einen Bereich zu Verfügung stellt, der keiner WebAnwendung zugeordnet ist (root context). Als Teil einer Web-Anwendung werden Servlets über den Namen der Anwendung identifiziert.
– Web-Anwendung hat einen Namen, über den sie identifiziert wird:
Beispiel: Web-Anwendung demo
→ http://localhost:8080/demo/servlet/Hello
– abhängig vom Servlet-Container können weitere Namen zugeordnet werden → ist
Servlet Hello weiterer Name hi zugeordnet:
http://localhost:8080/demo/hi
– ggf. mit Paketname: http://localhost/servlet/pi.vorlesung.Hello wenn
Servlet-Klasse im Paket pi.vorlesung
– direkter Zugriff auf den Servlet-Container → Port-Nummer angeben
Beispiel: http://pi55.informatik.uni-siegen.de:8080/servlet/Hello
(also Port 8080, vorgegeben bei Tomcat)
3.5
Servlet Context
– Objekt mit Schnittstelle ServletContext repräsentiert Web-Anwendung
– ein Objekt pro Anwendung und pro Java-VM – üblicherweise also genau ein Objekt
pro Anwendung. Unterstützt der Servlet-Container aber verteilte Anwendungen, wird
auf jedem Rechner, auf dem die Anwendung läuft, jeweils eine Java-VM gestartet mit
jeweils einem ServletContext pro Anwendung.
– ermöglicht die Kommunikation mit dem Servlet-Container
– Abbildung von relativen auf absolute Pfade
– Verwaltung globaler Variablen der Anwendung
Operationen: setAttribute(), getAttribute()
4
4.1
Servlet-Lebenszyklus
Initialisierung
– Operation init führt Initialisierungen durch
– z.B. Datenbankverbindung aufbauen, komplexe Berechnungen durchführen
– wird nur einmal pro Servlet aufgerufen; nicht für jede Anfrage!
– Erzeugen/Initialisieren des Servlets
6
– beim Start des Servlet-Containers
oder
– beim ersten Aufruf des Servlets
Das Servlet wird beim Start des Servlet-Containers erzeugt und initialisiert, wenn es
explizit beim Servlet-Container angemeldet ist (wie das geht, hängt vom Container
ab). Andernfalls wird es beim ersten Aufruf erzeugt.
4.1.1
Initialisierungsparameter
– werden dem Servlet bei der Initialisierung mitgegeben
– erlauben die Konfiguration von Servlets
– Definition serverabhängig
– Tomcat: Angabe in der web.xml
<servlet>
<servlet-name>
Hello2
</servlet-name>
<servlet-class>
Hello2
</servlet-class>
<init-param>
<param-name>message</param-name>
<param-value>Nachricht im Initialisierungsp...</param-value>
</init-param>
</servlet>
Servlet-Code
– Zugriff auf die Initialisierungsparameter über ServletConfig.getInitParameter()
/* Hello2.java */
...
public void init ( ServletConfig config )
{
super.init ( config );
message = config.getInitParameter ( "message" );
if ( message == null )
message = "keine Nachricht!";
}
...
4.2
Ausführung
– Beim Aufruf eines Servlets wird ein neuer thread gestartet und die Operation service
ausgeführt
– HttpServlet: Anfrage an Operationen doGet(), doPost() usw. weiterleiten
– diese Operationen enthalten die eigentliche Funktionen des Servlets
7
– normalerweise existiert nur eine Instanz des Servlets, dessen Operationen in verschiedenen threads ausgeführt werden → Zugriffe auf gemeinsame Daten synchronisieren!
– Ausnahme: Servlet implementiert SingleThreadModel → eine Instanz pro Anfrage
4.3
Zerstörung
– Servlets können zerstört werden (ausgelöst durch Administrator oder weil lange nicht
benutzt) → Ressourcen sparen
– dazu wird Operation destroy aufgerufen
→ aufräumen, Datenbank-Verbindung schließen, Daten sichern o.ä.
– Vorsicht: man kann sich nicht darauf verlassen, daß destroy wirklich aufgerufen wird
– etwa, wenn der Servlet-Container abstürzt. Wichtige Daten sollten daher regelmäßig
gesichert werden und nicht erst, wenn die destroy-Operation aufgerufen wird.
5
Parameter
– Servlets können beim Aufruf Parameter übergeben werden
– Paar aus Name und Wert
– Wert ist immer eine Zeichenkette
– Übergabe auf zwei Arten:
1. Anhängen an Link
2. Erfassen im Formular
5.1
Parameter an Links
– werden hinter ? an URL angehängt
– mehrere Parameter durch & getrennt
– Beispiel:
http://localhost:8080/servlet/demo/Param?nachname=Meier&ort=...
– Übertragung mit HTTP-get-Befehl
5.1.1
Verarbeitung im Servlet
– in doGet-Operation; Parameter im HttpServletRequest enthalten
– Zugriffsoperationen:
String
Enumeration
Map
String[]
getParameter ( String name )
getParameterNames ()
getParameterMap ()
getParameterValues ( String name )
8
public class Param extends HttpServlet
{
public void doGet ( HttpServletRequest
request,
HttpServletResponse response )
throws IOException, ServletException
{
...
nachname = request.getParameter ( "nachname" );
...
}
...
5.2
Verarbeitung von Formularen
– HTML-Formulare bestehen aus
– Eingabefeldern für Texte, Listen, Ankreuzfelder
– Buttons zum Absenden (submit) und Löschen (reset) des Formularinhalts
– beim Absenden wird eine Aktion ausgeführt → URL verweist auf Servlet – allgemein
können als Aktion eines Formulars auch CGI-Programme und HTML-Seiten angegeben
werden, in denen die Formular-Daten z.B. von Javascript-Code verarbeitet wird.
– beim submit werden die Daten als Parameter an die URL übergeben
– zwei HTTP-Übertragungsmethoden:
1. get: Daten werden als Parameter an die URL angehängt
→ eher für einfache Daten
2. post: Daten werden vom HTTP-Server im Standard-Eingabekanal zur Verfügung
gestellt
→ eher für umfangreiche Daten, die weiterverarbeitet werden sollen (z.B. Speichern
in Datenbank)
In CGI-Programmen muß dieser Unterschied berücksichtigt werden: Parameter, die per
get übertragen wurden, werden in der in Abschnitt 5.1 beschriebenen Form in einer
Umgebungsvariable gespeichert. Das CGI-Programm muß diese Variable auslesen und
die Namen und Werte der Parameter extrahieren. Dies wird z.B. in Perl durch spezielle
Funktionsbibliotheken erleichtert.
Bei post-Parametern muß dagegen stdin abgefragt und die einzelnen Parameter extrahiert werden. Das CGI-Programm muß also die verwendete Übertragungsmethode
kennen oder so programmiert sein, daß es die verwendete Methode ermittelt.
Bei Servlets ist eine solche Unterscheidung nicht nötig: Der Servlet-Container übernimmt automatisch die Konvertierung und stellt dem Servlet die Parameter immer im
HttpServletRequest zur Verfügung.
6
Sitzungen
– HTTP zustandslos → zwei aufeinanderfolgende Aufrufe können nicht dem gleichen
Benutzer zugeordnet werden!
– oft müssen Daten/Zustand der bisherigen Interaktionen bewahrt bleiben (Benutzername, selektierte Einträge, Einkaufskorb. . . ) → Sitzungen (Sessions) nötig
9
– also zusammenhängende Folge von Anforderungen und Antworten
– bei CGI: Sitzungen mit Cookies, zusätzlichen Parametern in URL (URL rewriting),
versteckten Werte in Formularen realisierbar
6.1
Sitzungen mit Servlets
– Session durch Objekt mit Schnittstelle HttpSession repräsentiert
– Zugriff auf Informationen über Session (Erzeugungs-, Zugriffszeit. . . )
– Speichern von Daten in der Session
→ setAttribute(), getAttribute()
– wird im HttpServletRequest mitgeliefert:
HttpSession session = request.getSession ()
– Session wird automatisch vom Servlet-Container zerstört, wenn für eine einstellbare
Zeit nicht aktiv
→ setMaxInactiveInterval()
7
Zusammenfassung
– Servlets sind in Java geschrieben Programme zum Erzeugen dynamischer WebInhalte
– haben Vorteile gegenüber CGI-Programme
– laufen in Servlet Containern
– z.B. Apache Tomcat
– können Daten per HTTP-get und post verarbeiten
– automatische Verwaltung von Sessions
10
Herunterladen