Kapitel 3. Servlet-Grundlagen
|
|
- Ferdinand Otto
- vor 8 Jahren
- Abrufe
Transkript
1 Kapitel 3 Servlet-Grundlagen
2 78 Kapitel3 Wie bereits in Kapitel 1 erwähnt wurde, sind Servlets Java-Programme, die auf einem Web- oder Anwendungsserver ausgeführt werden. Sie fungieren als Zwischenebene zwischen den Anfragen, die von den Webbrowsern oder anderen HTTP-Clients kommen, und den Datenbanken oder Anwendungen auf dem HTTP-Server, siehe Abbildung 3.1. Datenbank Legacy-Anwendung Java-Anwendung Client (Endanwender) Webserver (Servlets/JSP) Webdienst Abbildung 3.1: Die Aufgabe der Web-Zwischenebene (Middleware) 1. Die vom Client gesendeten, expliziten Daten lesen. Diese Daten werden normalerweise vom Benutzer in ein HTML-Formular auf einer Webseite eingegeben. Sie können aber auch von einem Applet oder einem selbst geschriebenen HTTP-Clientprogramm kommen. 2. Die vom Browser implizit mit der HTTP-Anfrage gesendeten Daten lesen. In Abbildung 3.1 sehen Sie nur einen Pfeil vom Client zum Webserver (der Ebene, auf der Servlets und JSP ausgeführt werden). Genau genommen gibt es aber zwei Arten von Daten: die expliziten Daten, die der Benutzer in ein Formular eingibt, und die impliziten oder auch verborgenen HTTP-Informationen. Beide Arten sind für die effektive Entwicklung wichtig. Zu den HTTP-Informationen gehören Cookies, Informationen zu den vom Browser unterstützten Medientypen und Komprimierungsformaten, und so weiter. Näheres hierzu erfahren Sie in Kapitel Ergebnisse generieren. Hierzu kann es erforderlich sein, mit einer Datenbank zu kommunizieren, einen RMI- oder CORBA-Aufruf zu tätigen, einen Webdienst aufzurufen oder die Antwort direkt zu berechnen. Unter Umständen stehen Ihre Daten in einer relationalen Datenbank. Gut. Doch Ihre Datenbank spricht wahrscheinlich kein HTTP und gibt auch keine Ergebnisse in HTML zurück, sodass der Webbrowser nicht direkt mit der Datenbank kommunizieren kann. Doch selbst wenn dies möglich wäre, würden Sie dies aus Sicherheitsgründen wahrscheinlich ablehnen. Das gleiche Argument trifft auch für die meisten anderen Anwendungen zu. Deshalb wird eine Zwischenebene im Webserver benötigt, die die eingehenden Daten aus dem HTTP-Stream herauszieht, mit der Anwendung kommuniziert und die Ergebnisse in ein Dokument einbettet. 4. Die konkreten Daten (d.h. das Dokument) an den Client senden. Das Dokument kann in verschiedenen Formaten gesendet werden, unter anderem als Text (HTML oder XML), binär (GIF-Bilder) oder sogar in einem komprimierten Format wie gzip, das irgend einem zugrunde liegenden Format übergestülpt wurde. 5. Die impliziten HTTP-Antwortdaten senden. In Abbildung 3.1 weist genau ein Pfeil von der Zwischenebene des Webservers (dem Servlet oder der JSP-Seite) auf den Client. Genau genommen gibt es aber zwei Arten von gesendeten Daten: das Dokument selbst und die impliziten beziehungsweise verborgenen HTTP-Informationen. Und auch hier gilt, dass beide Arten für die effektive Entwicklung wichtig sind. Anhand der gesendeten HTTP-Antwortparameter wird dem Client (z.b. Browser) mit-
3 Servlet-Grundlagen 79 geteilt, welche Art Dokument zurückgeliefert wird (z.b. HTML), werden Cookies und Caching- Parameter gesetzt und ähnliche Aufgaben ausgeführt. Eine ausführliche Beschreibung dieser Aufgaben finden Sie in den Kapiteln 6 und 7. Prinzipiell sind Servlets nicht auf Web- oder Anwendungsserver zur Behandlung von HTTP-Anfragen beschränkt, sondern eignen sich auch für andere Typen von Servern. So könnte man z.b. Servlets in Mail- oder FTP-Server einbetten, um deren Funktionalität zu erweitern. In der Praxis haben sich diese Einsatzmöglichkeiten für Servlets jedoch noch nicht durchgesetzt, sodass hier ausschließlich auf HTTP- Servlets eingegangen werden soll. 3.1 Grundstruktur von Servlets Listing 3.1 skizziert ein einfaches Servlet zur Behandlung von GET-Anfragen. Für Leser, die mit HTTP nicht so vertraut sind: GET-Anfragen sind der übliche Anfragetyp, den Browser zum Abrufen von Webseiten verwenden. Ein Browser generiert diese Anfragen, wenn der Benutzer einen URL in die Adresszeile eintippt, einen Link auf einer Webseite anklickt oder ein HTML-Formular abschickt, das kein METHOD-Attribut oder METHOD="GET" spezifiziert. Servlets können aber auch POST-Anfragen handhaben, die erzeugt werden, wenn jemand ein HTML-Formular abschickt, in dem METHOD="POST" spezifiziert ist. Einzelheiten zur Verwendung von HTML-Formularen und den Unterschied zwischen GET und POST finden Sie in Kapitel 19. Listing 3.1: ServletTemplate.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ServletTemplate extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { // Verwenden Sie "request", um eingehende HTTP-Header // (z.b. cookies) und HTML-Formulardaten zu lesen. // Verwenden Sie "response", um den HTTP- // Antwortstatuscode und die Antwort-Header anzugeben // (z.b. Inhaltstyp, Cookies). PrintWriter out = response.getwriter(); // Verwenden Sie "out", um den Inhalt an den Browser zu // senden. Servlets werden normalerweise von HttpServlet abgeleitet und überschreiben doget beziehungsweise dopost, je nachdem, ob die Daten mit GET oder POST übermittelt werden. Wenn Sie sowohl GET als auch POST von demselben Servlet mit derselben Aktion behandeln lassen möchten, können Sie einfach doget veranlassen, dopost aufzurufen oder umgekehrt.
4 80 Kapitel3 Beide Methoden nehmen zwei Parameter entgegen: HttpServletRequest und HttpServletResponse. Mit HttpServletRequest haben Sie Zugriff auf alle eingehenden Daten. Die Klasse verfügt über Methoden, mit denen Sie feststellen können, ob Informationen wie z.b. Formulardaten (Anfrage), HTTP-Anfrage-Header oder der Hostname des Clients eingehen. Mit HttpServletResponse können Sie ausgehende Informationen, wie HTTP-Statuscode (200, 404 etc.) und Antwort-Header (Content-Type, Set-Cookie etc.), spezifizieren. Was jedoch am wichtigsten ist: HttpServletResponse verschafft Ihnen einen PrintWriter, mit dem Sie den Dokumentinhalt an den Client zurücksenden können. Einfache Servlets verwenden die meiste Mühe auf println-anweisungen, die die gewünschte Seite generieren. Formulardaten, HTTP-Anfrage- Header, HTTP-Antworten und Cookies werden in den nächsten Kapiteln detailliert behandelt. Da doget und dopost zwei Ausnahmen (ServletException und IOException) auslösen, müssen Sie diese in die Methodendeklaration aufnehmen. Zum Schluss müssen Sie noch die Klassen aus java.io (für PrintWriter etc.), javax.servlet (für HttpServlet etc.) und javax.servlet.http (für HttpServletRequest und HttpServletResponse) importieren. Es besteht jedoch keine Notwendigkeit, sich die Methodensignatur und die Importanweisungen zu merken. Laden Sie einfach die obige Vorlage von der Buch-CD oder aus dem Quellcode-Archiv unter / herunter und verwenden Sie diese als Ausgangsbasis für Ihre Servlets. 3.2 Ein Servlet, das einfachen Text generiert Listing 3.2 zeigt ein einfaches Servlet, das normalen Text generiert. Die Ausgabe des Servlets ist in Abbildung 3.2 zu sehen. Bevor wir jetzt weitermachen, wollen wir uns jedoch etwas Zeit nehmen und die Installation, Kompilierung und Ausführung dieses einfachen Servlets durchspielen. (Siehe auch Kapitel 2 finden für ausführliche Hinweise zur Installation.) Als Erstes müssen Sie sicherstellen: dass Ihr Server wie in Kapitel 2.3 beschrieben konfiguriert ist. dass Ihr Entwicklungs-CLASSPATH wie in Kapitel 2.7 beschrieben auf die notwendigen drei Einträge verweist: die Servlet-JAR-Datei, Ihr oberstes Entwicklungsverzeichnis, und».«. dass alle Tests aus Kapitel 2.8 erfolgreich durchgeführt werden können. Zweitens: Geben Sie javac HelloWorld.java ein oder teilen Sie Ihrer Entwicklungsumgebung mit, das Servlet zu kompilieren (z.b. durch Anklicken von BUILD in Ihrer IDE oder durch Auswählen des COM- PILE-Befehls aus dem emacs JDE-Menü). Damit kompilieren Sie Ihr Servlet in eine Datei namens HelloWorld.class. Drittens: Verschieben Sie HelloWorld.class in das Verzeichnis, in dem Ihr Server Servlets speichert, die in die Standardwebanwendung gehören. Die genaue Position hängt vom Server ab, lautet aber in der Regel install_dir/.../web-inf/classes (siehe Kapitel 2.10 für Einzelheiten). Für Tomcat verwenden Sie zum Beispiel install_dir/webapps/root/web-inf/classes, für JRun install_dir/servers/default/defaultear/default-war/web-inf/classes und für Resin install_dir/doc/web-inf/classes. Alternativ können Sie aber auch eine der in Kapitel 2.9 vorgestellten Techniken einsetzen, um die Klassendateien automatisch an die gewünschte Position zu verschieben.
5 Servlet-Grundlagen 81 Zum Schluss rufen Sie das Servlet auf. Hier kommt entweder der Standard-URL oder ein eigener, in der web.xml-datei definierter URL ins Spiel. Eine genaue Beschreibung finden Sie in Kapitel Zu Beginn eines Projekts werden Sie es sicherlich bequemer finden, mit dem Standard-URL zu arbeiten, sodass Sie die web.xml-datei nicht jedes Mal beim Testen eines neuen Servlets bearbeiten müssen. Wenn Sie allerdings konkrete Anwendungen installieren, werden Sie fast immer den Standard-URL deaktivieren und in der web.xml-datei explizite URLs zuweisen (siehe Kapitel 2.11). Im Übrigen unterstützen nicht alle Server die Verwendung eines Standard-URLs, BEA WebLogic verzichtet beispielsweise darauf. Abbildung 3.2 zeigt ein Servlet, auf das über den Standard-URL zugegriffen wird, wobei der Server auf der lokalen Maschine läuft. Listing 3.2: HelloWorld.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getwriter(); out.println("hello World"); Abbildung 3.2: Ausgabe von Ein Servlet, das HTML generiert Die meisten Servlets generieren HTML und keinen einfachen Text wie im vorigen Beispiel. Um HTML zu erstellen, sind drei zusätzliche Schritte erforderlich: 1. Sie teilen dem Browser mit, dass sie ihm HTML zuschicken. 2. Sie modifizieren die println-anweisungen so, dass sie eine gültige Webseite aufbauen. 3. Sie prüfen mithilfe eines HTML-Validierers, ob Ihre HTML-Dokumente formale Syntaxfehler enthalten.
6 82 Kapitel3 Für Punkt 1 setzen Sie den HTTP-Antwort-Header Content-Type auf text/html. Im Allgemeinen setzt die setheader-methode von HttpServletResponse die Header, aber es ist eine so häufige Aufgabe, den Inhaltstyp zu setzen, dass es hierfür eine spezielle setcontenttype-methode gibt. Am besten kennzeichnet man HTML durch den Typ text/html, sodass der Code folgendermaßen aussieht: response.setcontenttype("text/html"); HTML ist zwar der gebräuchlichste Dokumenttyp, den Servlets erstellen, aber es ist nicht unüblich, auch andere Dokumenttypen zu erzeugen. So kommt es z.b. recht häufig vor, dass man mit Servlets Excel- Tabellen (Inhaltstyp application/vnd.ms-excel siehe Kapitel 7.3), JPEG-Bilder (Inhaltstyp image/jpeg siehe Kapitel 7.5) und XML-Dokumente (Inhaltstyp text/xml) erzeugt. Außerdem verwenden Sie Servlets nur selten dazu, HTML-Seiten zu erzeugen, die ein relativ festes Format aufweisen (d.h. deren Layout sich bei jeder Anfrage nur wenig ändert). Für solche Fälle ist JSP normalerweise die bessere Wahl. JSP wird in Teil II dieses Buches, der mit Kapitel 10 beginnt, behandelt. Keine Sorge, wenn Sie mit HTTP-Antwort-Headern noch nicht vertraut sind; sie werden in Kapitel 7 noch detailliert behandelt. Beachten Sie, dass Sie die Antwort-Header setzen, bevor Sie irgendwelche Inhalte über den PrintWriter zurückgeben. HTTP-Antworten bestehen nämlich aus einer Statuszeile, einem oder mehreren Headern, einer leeren Zeile und dem eigentlichen Dokument. und zwar in genau dieser Reihenfolge. Da die Header in jeder beliebigen Reihenfolge stehen können und Servlets die Header im Puffer speichern, bis sie alle auf einmal gesendet werden, ist es zulässig, den Statuscode (ein Teil der ersten zurückgegebenen Zeile) auch noch nach den Headern zu setzen. Servlets speichern aber nicht notwendigerweise das gesamte Dokument, da die Benutzer unter Umständen für lange Seiten auch Teilresultate sehen möchten. Servlet-Engines dürfen die Ausgabe zum Teil im Puffer speichern, aber die Größe dieses Puffers ist nicht angegeben. Sie können sie mit der HttpServletResponse-Methode getbuffersize ermitteln oder mit setbuffersize einstellen. Sie können so lange Header setzen, bis der Puffer voll ist und tatsächlich an den Client gesendet wird. Wenn Sie unsicher sind, ob der Puffer bereits gesendet wurde, können Sie dies mit der Methode iscommitted nachprüfen. Trotz allem ist es am besten, wenn Sie einfach die Zeile setcontenttype vor allen anderen Zeilen, die PrintWriter verwenden, stellen. Warnung Setzen Sie den Inhaltstyp immer, bevor Sie das eigentliche Dokument übermitteln. Der zweite Schritt besteht darin, println-anweisungen aufzusetzen, die HTML statt eines einfachen Textes ausgeben. Listing 3.3 zeigt die Datei HelloServlet.java, das Beispiel-Servlet aus Kapitel 2.8, mit dem getestet wurde, ob der Server ordnungsgemäß funktioniert. Wie Abbildung 3.3 belegt, formatiert der Browser das Ergebnis als HTML und nicht als einfachen Text. Listing 3.3: HelloServlet.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
7 Servlet-Grundlagen 83 /** Einfaches Servlet zum Testen des Servers. */ public class HelloServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); String doctype = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(doctype + "<HTML>\n" + "<HEAD><TITLE>Hello</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>Hello</H1>\n" + "</BODY></HTML>"); Abbildung 3.3: Ausgabe von Der letzte Schritt besteht darin, sicherzustellen, dass Ihr HTML keine Syntaxfehler aufweist, die zu unvorhersehbaren Ergebnissen auf den verschiedenen Browsern führen könnten. In Abschnitt 3.5 werden HTML-Validierer besprochen. 3.4 Servlet-Pakete In einer Produktionsumgebung erstellen eventuell mehrere Programmierer Servlets für denselben Server. Wenn man alle diese Servlets in dasselbe Verzeichnis legen würde, ließe sich die unüberschaubare Sammlung von Klassen kaum noch verwalten und es käme zu Namenskonflikten, wenn zufällig zwei Entwickler den gleichen Namen für Servlets oder Hilfsklassen verwenden. Mit Hilfe von Webanwendungen (siehe Kapitel 2.11) lässt sich dieses Problem einfach lösen, indem Sie alles auf getrennte Unterverzeichnisse, jedes mit seinem eigenen Satz an Servlets, Hilfsklassen, JSP-Seiten und HTML-Dateien verteilen. Da jedoch auch einzelne Webanwendungen recht umfangreich werden können, benötigen Sie trotzdem noch Javas Standardlösung zur Vermeidung von Namenskonflikten: die Pakete. Darüber hinaus müssen, wie Sie später noch sehen werden, selbst definierte Klassen, die von JSP-Seiten verwendet werden, immer in Paketen abgelegt werden. Gewöhnen Sie sich also möglichst früh an den Gebrauch von Paketen.
8 84 Kapitel3 Um Servlets in Pakete zu packen, sind zwei Schritte erforderlich: 1. Sie verschieben die Dateien in ein Unterverzeichnis, das mit dem gewünschten Paketnamen übereinstimmt. Wir werden z.b. für die meisten Servlets, die in diesem Buch noch vorkommen, das Paket coreservlets verwenden. Die Klassendateien gehören folglich in ein Unterverzeichnis mit dem Namen coreservlets. Denken Sie an die Groß- und Kleinschreibung. Sie ist sowohl für Paket- als auch für Verzeichnisnamen wichtig, unabhängig davon, welches Betriebssystem Sie verwenden. 2. Sie fügen eine package-anweisung in die Klassendatei ein. Damit z.b. eine Klasse einem Paket namens einpaket angehört, muss die Klassendatei in dem Verzeichnis einpaket liegen und die erste Zeile der Datei, die kein Kommentar ist, muss lauten: package einpaket; Listing 3.4 definiert z.b. eine Variante der Klasse HelloServlet, die sich im Paket coreservlets und damit im Verzeichnis coreservlets befindet. Wie bereits in Kapitel 2.8 besprochen wurde, sollte die Klassendatei für Tomcat in install_dir/webapps/root/web-inf/classes/coreservlets, für JRun in install_dir/servers/default/default-ear/default-war/web-inf/classes/coreservlets und für Resin in install_dir/doc/web-inf/classes/coreservlets stehen. Andere Server verfügen über ähnlich lautende Standardverzeichnisse. Abbildung 3.4 zeigt das Servlet, auf das mittels des Standard-URLs zugegriffen wird. Listing 3.4: coreservlets/helloservlet2.java package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Einfaches Servlet zum Testen von Paketen. */ public class HelloServlet2 extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); String doctype = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(doctype + "<HTML>\n" + "<HEAD><TITLE>Hello (2)</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>Hello (2)</H1>\n" + "</BODY></HTML>");
9 Servlet-Grundlagen 85 Abbildung 3.4: Ausgabe von Einfache Hilfsklassen zum Erstellen von HTML Wie Sie wahrscheinlich bereits wissen, besitzen HTML-Dokumente folgenden Aufbau: <!DOCTYPE...> <HTML> <HEAD><TITLE>...</TITLE>...</HEAD> <BODY...>...</BODY> </HTML> Wenn Sie jetzt beginnen, HTML mit Servlets erzeugen, sind Sie vielleicht in Versuchung, Teile dieser Grundstruktur insbesondere die DOCTYPE-Zeile wegzulassen, da diese Zeile, obwohl von der HTML- Spezifikation vorgeschrieben, von fast allen wichtigen Browsern ignoriert wird. Davon können wir nur entschieden abraten. Die DOCTYPE-Zeile wird benötigt, um HTML-Validierern die von Ihnen benutzte HTML-Version mitzuteilen. So wissen die Validierer, anhand welcher Spezifikation sie Ihr Dokument prüfen müssen. Validierer sind wertvolle Debug-Programme, die Ihnen helfen, Syntaxfehler aufzuspüren, die Ihr eigener Browser womöglich kompensiert, die anderen Browsern aber Schwierigkeiten bereiten können. Die beiden am weitesten verbreiteten Online-Validierer sind die Validierer des World Wide Web Consortiums ( und der Web Design Group ( validator/). Diesen können Sie einen URL senden, damit sie die Seite aufrufen, die Syntax an Hand der formalen HTML-Spezifikation überprüfen und Ihnen die Fehler zurückmelden. Da ein Servlet, das HTML generiert, für den Client wie eine normale Webseite aussieht, kann es in der gleichen Weise validiert werden solange es nicht auf POST-Daten angewiesen ist. Anders Servlets, die GET-Daten verarbeiten. Da GET-Daten an den URL angehängt werden, können Sie den URL mit den GET-Daten an den Validierer übergeben. Wenn das Servlet nur innerhalb Ihre Corporate Firewall verfügbar ist, führen Sie es einfach aus, sichern Sie den erzeugten HTML-Code auf Platte und wählen Sie die Validierer-Option FILE UPLOAD. Hinweis Prüfen Sie die Syntax der von Ihren Servlets generierten Seiten mit einem HTML-Validierer.
10 86 Kapitel3 Zugegebenermaßen ist es manchmal ein bisschen umständlich, HTML mit println-anweisungen zu generieren, besonders bei so langen Zeilen wie der DOCTYPE-Deklaration. Manche Entwickler lösen dieses Problem, indem sie in Java umfangreiche Hilfsprogramme schreiben, die HTML generieren und die sie dann in ihren Servlets einsetzen. Uns scheint die Nützlichkeit einer solchen Programmbibliothek jedoch zweifelhaft. Zum einem ist die umständliche HTML-Generierung mittels Programmen ja gerade eines der Hauptprobleme zu deren Lösung die JavaServer Pages entwickelt wurden (siehe Kapitel 10). Zweitens sind Routinen zum Generieren von HTML oft sperrig und unterstützen selten alle HTML-Attribute (CLASS und ID für Stylesheets, JavaScript-Ereignisbehandungscode, Hintergrundfarben für Tabellenzellen und so weiter). Trotz des fragwürdigen Werts einer voll ausgereiften Bibliothek zur Erzeugung von HTML-Code spricht nichts gegen die Implementierung einzelner Hilfsklassen: Wenn Sie beispielsweise feststellen, dass Sie immer wieder dieselben Konstrukte ausgeben, können Sie hierfür ebenso gut eine einfache Hilfsklasse schreiben. Schließlich arbeiten Sie mit der Programmiersprache Java; denken Sie also die an das Grundprinzip der objektorientierten Programmierung, das Code wieder verwendet und nicht wiederholt werden sollte. Die Wiederholung identischen oder beinahe identischen Codes bedeutet, dass Sie den Code an vielen Stellen ändern müssen, wenn Sie später Ihren Ansatz ändern. Zwei Teile der von normalen Servlets erzeugten Webseiten ändern sich in der Regel kaum: DOCTYPE und HEAD. Es bietet sich daher an, für diese eine einfache Hilfsprogrammdatei zu schreiben. Den Quelltext dieser Datei sehen Sie in Listing 3.5. Eine Variante der Klasse HelloServlet, die diese Hilfsklasse nutzt, finden Sie in Listing 3.6. Im Laufe des Buchs werden wir noch einige weitere Hilfsklassen erstellen. Listing 3.5: coreservlets/servletutilities.java package coreservlets; import javax.servlet.*; import javax.servlet.http.*; /** Einige einfache Konstrukte, zumeist statische Methoden, die Ihnen Zeit sparen können. */ public class ServletUtilities { public static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">"; public static String headwithtitle(string title) { return(doctype + "\n" + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n");...
11 Servlet-Grundlagen 87 Listing 3.6: coreservlets/helloservlet3.java package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Einfaches Servlet, mit dem der Einsatz von * Paketen und Hilfsklassen desselben Pakets * getestet werden kann. */ public class HelloServlet3 extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); String title = "Hello (3)"; out.println(servletutilities.headwithtitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>" + title + "</H1>\n" + "</BODY></HTML>"); Nachdem Sie HelloServlet3.java kompiliert haben (wodurch ServletUtilities.java automatisch mitkompiliert wird), müssen Sie die zwei Klassendateien in das Unterverzeichnis coreservlets des verwendeten Deployment-Verzeichnisses des Servers (.../WEB-INF/classes; siehe Kapitel 2.8 für nähere Einzelheiten) verschieben. Wenn Sie beim Kompilieren von HelloServlet3.java eine»unresolved Error«-Fehlermeldung erhalten, prüfen Sie noch einmal Ihre CLASSPATH-Einstellungen (siehe Kapitel 2.7 ), besonders die Angabe des obersten Entwicklungsverzeichnis. In Abbildung 3.5 sehen Sie das Ergebnis, wenn das Servlet mit dem Standard-URL aufgerufen wird. Abbildung 3.5: Ausgabe von
12 88 Kapitel3 3.6 Lebenszyklus von Servlets In Kapitel 1.4 wurde bereits angesprochen, dass immer nur eine einzige Instanz eines Servlets erzeugt wird und für jede Benutzeranfrage ein neuer Thread gestartet wird, der je nach Anfragetyp doget oder dopost ausführt. Nun soll etwas genauer erläutert werden, wie Servlets erzeugt und aufgelöst werden, und wie und wann die verschiedenen Methoden aufgerufen werden. Wir beginnen mit einer kurzen Zusammenfassung, in den nächsten Unterabschnitten folgen dann die Einzelheiten. Wenn ein Servlet erzeugt wird, wird seine init-methode aufgerufen. In diese schreiben Sie folglich den Setup-Code, der nur einmal ausgeführt werden soll. Danach erzeugt jede Benutzeranfrage einen Thread, der die service-methode der zuvor erzeugten Instanz aufruft. Mehrere, zeitgleiche Anfragen erzeugen in der Regel mehrere Threads, die service parallel aufrufen (Ihr Servlet kann aber auch eine spezielle Schnittstelle (SingleThreadModel) implementieren, die festlegt, dass jeweils nur ein einziger Thread gleichzeitig ausgeführt werden darf). Danach ruft die service-methode je nach der der von ihr empfangenen HTTP- Anfrage doget, dopost oder eine andere doxxx-methode auf. Wenn schließlich der Server beschließt, ein Servlet aus dem Speicher zu entfernen, ruft er als Erstes die destroy-methode dieses Servlets auf Die service-methode Immer wenn der Server die Anfrage nach einem Servlet empfängt, erzeugt er einen neuen Thread und ruft service auf. Die Methode service stellt den HTTP-Anfragetyp fest (GET, POST, PUT, DELETE etc.) und ruft entsprechend doget, dopost, doput, dodelete etc. auf. GET-Anfragen werden gesendet, wenn ein normaler URL angefordert oder ein HTML-Formular, für das kein METHOD-Attribut spezifiziert wurde, abgeschickt wird. POST-Anfragen werden für HTML-Formulare erzeugt, die als METHOD explizit POST angeben. Andere HTTP-Anfragen werden nur von selbst definierten Clients erzeugt. Wenn Sie mit HTML-Formularen noch nicht so vertraut sind, lesen Sie Kapitel 19. Für Servlet, die POST- und GET-Anfragen identisch behandeln, könnten Sie vielleicht in Versuchung geraten, service direkt zu überschreiben, anstatt doget und dopost zu implementieren. Das ist keine gute Idee. Sorgen Sie stattdessen dafür, dass dopost die Methode doget aufruft (oder umgekehrt): public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { // Servlet-Code public void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { doget(request, response); Dieser Ansatz erfordert zwar ein paar Codezeilen mehr, aber er hat gegenüber dem Überschreiben von service mehrere Vorteile. Erstens können Sie später noch Unterstützung für andere HTTP-Anfragemethoden hinzufügen, indem Sie vielleicht in einer abgeleiteten Klasse doput, dotrace etc. definieren. Wenn Sie service direkt überschreiben, ist diese Möglichkeit ausgeschlossen. Zweitens können Sie das Änderungsdatum verarbeiten, indem Sie eine getlastmodified-methode, wie in Listing 3.7 zu sehen, hin-
13 Servlet-Grundlagen 89 zufügen. Da getlastmodified von der ursprünglichen service-methode aufgerufen wird, berauben Sie sich durch Überschreiben von service dieser Option. Und schließlich erhalten Sie durch service automatisch Unterstützung für HEAD-, OPTION- und TRACE-Anfragen. Hinweis Wenn Ihr Servlet GET und POST identisch behandeln muss, lassen Sie Ihre dopost-methode doget aufrufen oder umgekehrt. Überschreiben Sie auf keinen Fall die Methode service Die Methoden doget, dopost und doxxx Diese Methoden enthalten die eigentliche Substanz Ihres Servlets. 99 Prozent der Zeit werden Sie sich nur über GET oder POST-Anfragen und die Überschreibung der Methoden doget und/oder dopost Gedanken machen. Wenn Sie möchten, können Sie aber auch dodelete für DELETE-Anfragen, doput für PUT-Anfragen, dooptions für OPTIONS-Anfragen und dotrace für TRACE-Anfragen überschreiben. Denken Sie jedoch daran, dass Sie automatische Unterstützung für OPTIONS und TRACE haben. Normalerweise müssen Sie dohead nicht implementieren, um HEAD-Anfragen zu behandeln (HEAD-Anfragen fordern, dass der Server die normalen HTTP-Header ohne dazugehöriges Dokument zurückliefert). Das liegt daran, dass das System zum Beantworten von HEAD-Anfragen automatisch die Statuszeile und Header-Einstellungen von doget benutzt. Manchmal kann es jedoch nützlich sein, dohead zu implementieren, damit Sie schneller Antworten auf HEAD-Anfragen erzeugen können (d.h. auf Anfragen von selbst geschriebenen Clients, die nur die HTTP-Header und nicht das eigentliche Dokument anfordern) ohne das eigentliche Dokument zur Ausgabe mit erzeugen zu müssen Die init-methode In den meisten Fällen verarbeiten Ihre Servlets allein die Daten der Anfrage, und die einzigen Methoden aus Lebenszyklus des Servlets, die Sie benötigen, sind doget und dopost. Gelegentlich kann es jedoch vorkommen, dass Sie beim ersten Laden des Servlets komplexere Initialisierungen durchführen möchten, die später nicht für jede Anfrage wiederholt werden sollen. Für diese Fälle wurde die init-methode entworfen. Sie wird nur zu Beginn des Lebenszyklus aufgerufen, wenn das Servlet erzeugt wird; für nachfolgende Benutzeranfragen wird sie nicht mehr erneut aufgerufen. Sie wird also, genau wie die init- Methode der Applets, für einmalige Initialisierungen eingesetzt. Normalerweise wird ein Servlet erzeugt, wenn irgendein Benutzer den URL, der zu dem Servlet gehört, zum ersten Mal aufruft. Sie können aber auch vorgeben, dass das Servlet geladen wird, wenn der Server das erste Mal gestartet wird (mithilfe der Datei web.xml). Die Definition der init-methode sieht folgendermaßen aus: public void init() throws ServletException { // Initialisierungscode... Die init-methode führt zwei Arten der Initialisierung aus: allgemeine Initialisierungen und Initialisierungen, die von Initialisierungsparameter gesteuert werden.
14 90 Kapitel3 Allgemeine Initialisierung Bei der ersten Form der Initialisierung erzeugt oder lädt init einfach einige Daten, die während der Lebensdauer des Servlets verwendet werden, oder es führt bestimmte einmalige Berechnungen durch. Man kann dies mit einem Applet vergleichen, das getimage aufruft, um Bilddateien über das Netzwerk zu laden: Die Operation muss nur einmal durchgeführt werden und wird deshalb in init angestoßen. Einmalige Servlet-typische Aufgaben wären das Einrichten eines Datenbankverbindungspool für Anfragen, die das Servlet behandelt, oder das Laden einer Datendatei in eine HashMap. Listing 3.7 zeigt ein Servlet, das init für zweierlei Dinge verwendet. Zum einen baut es ein Array von 10 ganzen Zahlen auf. Da diese Zahlen das Ergebnis komplexer Berechnungen sind, sollen diese Berechnungen nicht für jede Anfrage wiederholt werden. Deshalb schaut doget die von init berechneten Werte nach, anstatt diese Werte immer neu zu generieren. Abbildung 3.6 zeigt die Ergebnisse dieser Technik. Des Weiteren speichert das Servlet in init das Datum der letzten Überarbeitung, welches später von der getlastmodified-methode benutzt wird, und nutzt dabei den Umstand, dass sich seine Ausgabe nur ändert, wenn der Server neu hochgefahren wird. Die getlastmodified-methode sollte eine Änderungszeit zurückgeben, die gemäß dem Standard für Datumsangaben in Java in Millisekunden seit 1970 ausgedrückt ist. Diese Zeit wird automatisch in das für den Last-Modified-Header geeignete GMT-Datum umgerechnet. Was jedoch noch wichtiger ist: Wenn der Server eine bedingte GET-Anfrage empfängt (die spezifiziert, dass der Client nur Seiten möchte, die seit einem bestimmten Datum geändert wurden und mit If-Modified-Since gekennzeichnet sind), vergleicht das System das angegebene Datum mit dem von getlastmodified zurückgegebenen Datum und liefert dem Client die Seite nur dann, wenn diese nach dem angegebenen Datum geändert worden ist. Da Browser oft solche bedingten Anfragen nach Seiten senden, die in ihren Caches gespeichert sind, kommt eine Unterstützung der bedingten Anfrage letztlich Ihren Benutzern zugute (sie erhalten schnellere Ergebnisse) und reduziert die Serverlast (Sie senden weniger vollständige Dokumente). Weil die Header Last-Modified und If-Modified-Since nur ganze Sekunden berücksichtigen, sollte die getlastmodified-methode die Zeitangaben auf die nächste Sekunde runden. Listing 3.7: coreservlets/lotterynumbers.java package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Beispiel mit Servlet-Initialisierung und der Methode * getlastmodified. */ public class LotteryNumbers extends HttpServlet { private long modtime; private int[] numbers = new int[10]; /** Die init-methode wird nur beim erstmaligen Laden des * Servlets aufgerufen, bevor die erste Anfrage * verarbeitet wird. */
15 Servlet-Grundlagen 91 public void init() throws ServletException { // Runde auf Sekunde auf (d. h Millisekunden) modtime = System.currentTimeMillis()/1000*1000; for(int i=0; i<numbers.length; i++) { numbers[i] = randomnum(); /** Liefere die Liste der in init berechneten Zahlen zurück. */ public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); String title = "Your Lottery Numbers"; String doctype = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(doctype + "<HTML>\n" + "<HEAD><TITLE>"+title+"</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<B>Based upon extensive research of " + "astro-illogical trends, psychic farces, " + "and detailed statistical claptrap, " + "we have chosen the " + numbers.length + " best lottery numbers for you.</b>" + "<OL>"); for(int i=0; i<numbers.length; i++) { out.println(" <LI>" + numbers[i]); out.println("</ol>" + "</BODY></HTML>"); /** Die originale service-methode vergleicht dieses Datum * mit dem Datum aus dem If-Modified-Since-Anfrage- * Header. Wenn das getlastmodified-datum neuer oder * kein If-Modified-Since-Header vorhanden ist, wird die * doget-methode normal aufgerufen. Ist jedoch das * getlastmodified-datum gleich oder liegt es früher, * so sendet die service-methode eine 304er-Antwort * (Not Modified) zurück und ruft doget <B>nicht</B> auf. * Der Browser soll in diesem Fall seine im * Cache befindliche Version der Seite verwenden. */ public long getlastmodified(httpservletrequest request) {
16 92 Kapitel3 return(modtime); // Eine Zufallszahl vom Typ int zwischen 0 und 99. private int randomnum() { return((int)(math.random() * 100)); Abbildung 3.6: Ausgabe des Servlets LotteryNumbers. Abbildung 3.7 und Abbildung 3.8 zeigen das Ergebnis von Anfragen mit zwei leicht voneinander abweichenden If-Modified-Since-Datumsangaben an dasselbe Servlet. Um die Anfrage-Header zu setzen und die Antwort-Header zu sehen, wurde WebClient verwendet, eine Java-Anwendung, mit der Sie HTTP- Anfragen interaktiv einrichten, absenden und die Ergebnisse anzeigen lassen können. Der Code für WebClient ist im Quellcode-Archiv auf der Homepage zu diesem Buch zu finden ( Initialisierungen, die durch Initialisierungsparameter gesteuert sind In dem obigen Beispiel berechnete die init-methode verschiedene Daten, die von den doget- und getlastmodified-methoden verwendet wurden. Obwohl diese Art der allgemeinen Initialisierung weit verbreitet ist, findet man ebenso oft Code, bei dem die Initialisierung durch die Verwendung von Initialisierungsparametern gesteuert wird. Um verstehen zu können, warum Initialisierungsparameter eingesetzt werden, müssen Sie wissen, wer daran Interesse haben könnte, die Funktionsweise eines Servlets oder einer JSP-Seite zu beeinflussen. Es gibt insgesamt drei Gruppen:
17 Servlet-Grundlagen 93 Abbildung 3.7: Wenn man auf das Servlet LotteryNumbers mit einer un-bedingten GET-Anfrage oder mit einer bedingten Anfrage, die ein vor der Servlet-Initialisierung liegendes Datum angibt, zugreift, erhält man die normale Webseite zurück. Der Code für das WebClient-Programm, mit dem hier interaktiv eine Verbindung zum Server hergestellt wurde) ist im Quellcode-Archiv zu diesem Buch unter zu finden. 1. Entwickler. 2. Endnutzer. 3. Administratoren, die für die korrekte Installation verantwortlich sind. Entwickler ändern das Verhalten eines Servlets, indem Sie den Code verändern. Endnutzer ändern das Verhalten eines Servlets, indem sie Daten in ein HTML-Formular eingeben (vorausgesetzt der Entwickler hat vorgesehen, dass das Servlet nach diesen Daten Ausschau hält). Doch wie sieht es mit den Administratoren aus? Es muss auch für Administratoren eine Möglichkeit geben, Servlets von einer Maschine zu einer anderen zu verschieben und dabei bestimmte Parameter ändern zu können (z.b. die Adresse einer Datenbank, die Größe eines Verbindungspools oder den Speicherort einer Datendatei), ohne dafür gleich den Quellcode des Servlets anpassen zu müssen. Zu diesem Zwecke gibt es die Initialisierungsparameter.
18 94 Kapitel3 Abbildung 3.8: Wenn man auf das Servlet LotteryNumbers mit einer bedingten GET-Anfrage zugreift, die ein Datum nach der Servlet-Initialisierung angibt, erhält man die Antwort 304 (Not Modified). Da die Verwendung von Initialisierungsparametern bei Servlets im starken Maße von dem Deployment- Deskriptor (web.xml) abhängt, dessen ausführliche Behandlung außerhalb der Möglichkeiten dieses Buches liegt, beschränken wir uns hier mit einem kurzen Überblick: 1. Verwenden Sie das web.xml-element servlet, um Ihrem Servlet einen Namen zu geben. 2. Verwenden Sie das web.xml-element servlet-mapping, um Ihrem Servlet einen eigenen URL zuzuweisen. Verwenden Sie niemals Standard-URLs der Form im Zusammenhang mit Initialisierungsparametern. (Tatsächlich werden diese Standard-URLs, so bequem sie zu Beginn eines neuen Projekts sein mögen, so gut wie nie für die konkrete Installation auf dem Zielserver verwendet. 3. Ergänzen Sie das web.xml-element servlet um init-param-unterelemente, um die Initialisierungsparameter mit Namen und Werten auszustatten. 4. Rufen Sie in der init-methode Ihres Servlets getservletconfig auf, um eine Referenz auf das ServletConfig-Objekt zu erhalten.
19 Servlet-Grundlagen Rufen Sie die getinitparameter-methode von ServletConfig mit dem Namen des Initialisierungsparameters auf. Der Rückgabewert ist der Wert des Initialisierungsparameters oder null, wenn in der web.xml-datei kein solcher Initialisierungsparameter gefunden wird Die destroy-methode Unter Umständen entscheidet sich der Server, eine zuvor geladene Instanz eines Servlets zu entfernen, vielleicht, weil der Server-Administrator dies explizit verlangt, vielleicht aber auch, weil das Servlet sehr lange untätig geblieben ist. Bevor er dies jedoch macht, ruft er die destroy-methode des Servlets auf. Diese Methode gibt Ihrem Servlet eine Chance, Datenbankverbindungen zu schließen, im Hintergrund ablaufende Threads anzuhalten, Cookie-Listen oder Zugriffszählungen auf die Festplatte zu schreiben und andere vergleichbare Abschlussarbeiten vorzunehmen. Sie müssen jedoch immer auch damit rechnen, dass der Webserver abstürzen kann (denken Sie an die weltweit grassierenden Stromausfälle). Verlassen Sie sich also nicht auf destroy als einzigen Mechanismus, um den Zustand auf der Festplatte zu speichern. Auch Aktivitäten wie ein Zugriffszähler oder angesammelte Listen von Cookie-Werten, die speziellen Zugriff anzeigen, sollten ihren Zustand vorsorglich in regelmäßigen Abständen auf die Festplatte schreiben. 3.7 Die Schnittstelle SingleThreadModel Normalerweise erzeugt das System eine einzige Instanz Ihres Servlets und erstellt dann für jede Benutzeranfrage einen neuen Thread, wobei mehrere Threads parallel ablaufen, wenn eine neue Anfrage eintrifft und eine vorangegangene Anfrage noch nicht abgearbeitet ist. Folglich müssen Ihre Methoden doget und dopost darauf achten, dass sie den Zugriff auf Felder und andere gemeinsam genutzte Daten (falls vorhanden) synchronisieren, da eventuell mehrere Threads gleichzeitig versuchen, auf diese Daten zuzugreifen. (Lokale Variablen werden nicht von mehreren Threads gemeinsam genutzt und benötigen deshalb keinen besonderen Schutz.) Wenn Sie den gleichzeitigen Zugriff durch mehrere Threads verhindern möchten, können Sie Ihr Servlet wie unten dargestellt die Schnittstelle SingleThreadModel implementieren lassen. public class YourServlet extends HttpServlet implements SingleThreadModel {... Wenn Sie diese Schnittstelle implementieren, gewährleistet das System, dass nie mehr als ein Anfrage- Thread auf eine einzelne Instanz Ihres Servlets zugreift. Dazu stellt es meistens alle Anfragen in eine Schlange und übergibt sie nacheinander einer einzigen Instanz des Servlets. Allerdings darf der Server auch einen Pool mit mehreren Instanzen erzeugen, die jeweils immer nur eine Anfrage behandeln. In beiden Fällen brauchen Sie sich nicht um gleichzeitige Zugriffe auf reguläre Felder (Instanzvariablen) des Servlets zu sorgen. Deswegen müssen Sie aber immer noch den Zugriff auf Klassenvariablen (als static deklarierte Felder) oder auf gemeinsam genutzte Daten außerhalb des Servlets synchronisieren. Doch auch wenn SingleThreadModel den zeitgleichen Zugriff vom Prinzip her verhindert, gibt es aus praktischer Sicht zwei Gründe, warum man darauf verzichten sollte.
20 96 Kapitel3 Zum einen kann der synchronisierte Zugriff auf Ihre Servlets die Leistung stark beeinträchtigen (Latenz), wenn Ihr Servlet extrem stark frequentiert wird. Wenn ein Servlet auf E/A wartet, kann der Server anstehende Anfragen für dasselbe Servlet nicht entgegennehmen. Denken Sie also lieber zweimal nach, bevor Sie den SingleThreadModel-Ansatz wählen. Besser ist es, nur den Teil des Codes zu synchronisieren, der die gemeinsam genutzten Daten manipuliert. Ein weiteres Problem der SingleThreadModel-Schnittstelle ergibt sich dadurch, dass die Spezifikation es den Servern gestattet, Instanzen-Pools zu verwenden, anstatt die Anfragen in eine Warteschlange zu stellen und an eine einzelne Instanz zu übergeben. Solange jede Instanz nur eine Anfrage zurzeit bearbeitet, genügt der Instanzen-Pool-Ansatz den Anforderungen der Spezifikation. Aber auch er ist keine gute Lösung. Nehmen wir an, dass wir reguläre, nicht als static deklarierte Instanzvariablen (Felder) verwenden, um auf gemeinsam verwendete Daten zuzugreifen. Zwar verhindert die SingleThreadModel-Schnittstelle den gleichzeitigen Zugriff, aber dazu schüttet sie auch gleich das Baby mit dem Wasser aus, denn jede Servlet-Instanz besitzt eine eigene Kopie der Instanzvariablen, sodass man nicht mehr von echter gemeinsamer Nutzung der Daten sprechen kann. Wie sieht es dagegen aus, wenn wir als static deklarierte Instanzvariablen verwenden, um auf gemeinsam verwendete Daten zuzugreifen. In diesem Fall bietet der Instanzen-Pool-Ansatz zu SingleThreadModel keinerlei Vorteil. Immer noch können mehrere Anfragen (unter Verwendung verschiedener Instanzen) zeitgleich auf die statischen Daten zugreifen. Und doch ist die SingleThreadModel-Schnittstelle gelegentlich durchaus nützlich. Zum Beispiel kann sie eingesetzt werden, wenn die Instanzvariablen für jede Anfrage neu initialisiert werden (wenn sie z.b. nur dazu verwendet werden, die Kommunikation zwischen den Methoden zu vereinfachen). Im Großen und Ganzen sind die Probleme mit der Schnittstelle SingleThreadModel jedoch so gravierend, dass sie in der Servlet-Spezifikation 2.4 (JSP 2.0) als veraltet eingestuft wurde. Wir empfehlen Ihnen, stattdessen lieber die expliziten synchronized-blöcke zu verwenden. Warnung Vermeiden Sie die Implementierung von SingleThreadModel für stark frequentierte Servlets. Verwenden Sie die Schnittstelle auch sonst nur mit größter Vorsicht. Für die endgültigen Versionen Ihrer Servlets ist die explizite Codesynchronisation fast immer die bessere Wahl. Ab Version 2.4 der Servlet-Spezifikation ist SingleThreadModel veraltet. Betrachten wir beispielsweise das Servlet aus Listing 3.8, das versucht jedem Client eine eindeutige Benutzer-ID zuzuweisen (eindeutig, bis der Server neu startet). Es verwendet eine Instanzvariable (Feld) namens nextid, um zu verfolgen, welche ID als Nächstes zugewiesen werden soll, und verwendet den folgenden Code, um die ID auszugeben. String id = "User-ID-" + nextid; out.println("<h2>" + id + "</H2>"); nextid = nextid + 1;
21 Servlet-Grundlagen 97 Nehmen wir einmal an, Sie wären sehr vorsichtig beim Testen dieses Servlets. Sie würden es in ein Unterverzeichnis namens coreservlets ablegen, es kompilieren und das coreservlets-verzeichnis in das Verzeichnis WEB-INF/classes der Standardwebanwendung kopieren (siehe Abschnitt 2.10). Anschließend würden Sie den Server starten und mehrmals mit auf das Servlet zugreifen. Bei jedem Zugriff erhielten Sie einen anderen Wert (Abbildung 3.9) Also ist Ihr Code korrekt, nicht wahr? Falsch! Das Problem tritt erst auf, wenn es mehrere gleichzeitige Zugriffe auf das Servlet gibt. Und auch dann nur sporadisch. Aber es kann passieren, dass in einigen Fällen der erste Client das nextid-feld liest und dann auf Grund des präemptiven Multitasking die Kontrolle über den Thread entzogen bekommt, bevor er das Feld inkrementiert hat. Anschließend könnte ein zweiter Client das Feld lesen und erhielte den gleichen Wert wie der erste Client. Das ist schlecht! So hat es zum Beispiel tatsächlich E-Commerce-Anwendungen gegeben, in denen Kundenkäufe gelegentlich auf einer falschen Kundenkreditkarte abgerechnet wurden, und Schuld waren genau die hier beschriebenen Konkurrenzsituationen bei der Erzeugung von Benutzer-IDs. Wenn Sie sich in der Multithread-Programmierung auskennen, ist Ihnen das Problem sicher gleich aufgefallen. Die Frage ist nur, welches ist die geeignete Lösung? Sehen Sie im Folgenden drei Möglichkeiten: 1. Verkürzen Sie die Konkurrenzsituation. Löschen Sie die dritte Zeile des Codefragments und ändern sie die erste Zeile in: String id = "User-ID-" + nextid++; Puuh! Durch diesen Ansatz ist die Wahrscheinlichkeit einer falschen Antwort zwar geringer, aber die Möglichkeit besteht immer noch. In vielen Szenarien ist die Reduzierung der Wahrscheinlichkeit einer falschen Antwort eher von Nachteil denn von Vorteil: Es bedeutet lediglich, dass das Problem beim Testen schlechter aufzuspüren ist und wahrscheinlich genau dann auftritt, wenn die Testphase vorbei ist. 2. Verwenden Sie SingleThreadModel. Ändern sie die Servlet-Klassendefinition wie folgt. public class UserIDs extends HttpServlet implements SingleThreadModel { Funktioniert das? Wenn der Server SingleThreadModel implementiert, indem er alle Anfragen in eine Warteschlange stellt, dann mag das funktionieren. Allerdings auf Kosten der Leistung, wenn es viele gleichzeitige Zugriffe gibt. Und was noch schlimmer ist, wenn der Server SingleThreadModel implementiert, indem er einen Servletinstanzen-Pool einrichtet, ist dieser Ansatz gänzlich unbrauchbar, da jede Instanz sein eigenes nextid-feld hat. Beide Serverimplementierungsansätze sind gültig, sodass diese»lösung«keine Lösung darstellt. 3. Synchronisieren Sie den Code explizit. Verwenden Sie die in Java übliche Standardkonstruktion zur Synchronisierung. Beginnen Sie den synchronized-block direkt vor dem ersten Zugriff auf die gemeinsam genutzten Daten und beenden Sie den Block direkt nach der letzten Aktualisierung der Daten: synchronized(this) { String id = "User-ID-" + nextid; out.println("<h2>" + id + "</H2>"); nextid = nextid + 1;
22 98 Kapitel3 Damit teilen Sie dem System mit, dass sobald ein Thread in den obigen Codeblock (oder einen anderen synchronisierten Abschnitt, der mit der gleichen Objektreferenz gekennzeichnet wurde) eingetreten ist, kein anderer Thread Zugriff hat, bis der erste Thread den Block verlässt. Dies ist die Lösung, die immer in Java verfolgt wird. Sie ist auch hier die richtige Wahl. Vergessen Sie fehleranfällige und leistungsschwache SingleThreadModel-Abkürzungen. Beheben Sie Konkurrenzsituationen ordnungsgemäß. Listing 3.8: coreservlets/userids.java package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Servlet, das versucht, jedem Benutzer eine eindeutige * Benutzer-ID zuzuteilen. Da es jedoch versäumt, den * Zugriff auf das nextid-feld zu synchronisieren, kommt * es zu Konkurrenzsituationen zwischen den Threads. Folge: * Zwei Benutzer können die gleiche ID zugewiesen bekommen. */ public class UserIDs extends HttpServlet { private int nextid = 0; public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); String title = "Your ID"; String doctype = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(doctype + "<HTML>\n" + "<HEAD><TITLE>"+title+"</TITLE></HEAD>\n" + "<CENTER>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>" + title + "</H1>\n"); String id = "User-ID-" + nextid; out.println("<h2>" + id + "</H2>"); nextid = nextid + 1; out.println("</body></html>");
23 Servlet-Grundlagen 99 Abbildung 3.9: Ausgabe des Servlets UserIDs. 3.8 Servlets debuggen Wenn Sie ein Servlet schreiben, machen Sie natürlich nie Fehler. Doch der eine oder andere Ihrer Kollegen macht vielleicht gelegentlich einen Fehler und dann können Sie ihm die folgenden Ratschläge geben. Nein, ernsthaft, das Debuggen von Servlets kann knifflig werden, weil Sie sie nicht direkt ausführen. Stattdessen starten Sie sie mit einer HTML-Anfrage und der Webserver führt sie aus. Diese Remote-Ausführung erschwert es, Haltepunkte zu setzen oder Debug-Meldungen und Stack-Traces zu lesen. Daher unterscheiden sich die Ansätze beim Debuggen von Servlets etwas von denjenigen, die bei einer normalen Entwicklung eingesetzt werden. Hier sind zehn allgemeine Strategien, die Ihnen das Leben erleichtern können. 1. Verwenden Sie print-anweisungen. Die Server der meisten Anbieter blenden während der Ausführung des Servers auf dem Desktop ein Fenster für die Standardausgabe ein (d.h. die Ausgabe der System.out.println-Anweisungen).»Was?«werden Sie sagen,»sie wollen doch sicherlich nicht auf etwas so Veraltetes wie print-anweisungen zurückgreifen?«. Wir geben zu, dass es ohne Zweifel anspruchsvollere Debug-Techniken gibt, und wenn Sie damit vertraut sind, sollten Sie sie unbedingt anwenden. Aber es wird Sie überraschen, festzustellen, wie nützlich allein das Einholen von grundlegenden Informationen zu der Arbeitsweise Ihres Programms ist. Sie haben den Eindruck, die init-methode arbeitet nicht ordnungsgemäß? Fügen Sie eine print-anweisung ein, starten Sie den Server neu und prüfen Sie, ob die print-anweisung im Standardausgabefenster angezeigt wird. Vielleicht haben Sie init nicht korrekt deklariert, sodass Ihre Version nicht aufgerufen wird? Sie erhalten eine Ausnahme vom Typ NullPointerException? Fügen Sie einfach einige print-anweisungen ein, um festzustellen, in welcher Codezeile der Fehler erzeugt wird und welches Objekt auf der Zeile null war. Falls Sie Zweifel haben, holen Sie sich einfach mehr Informationen ein. 2. Verwenden Sie den in Ihre IDE integrierten Debugger. Viele integrierte Entwicklungsumgebungen (IDEs) verfügen über ausgereifte Debug-Tools, die in Ihre Servlet- und JSP-Container integriert werden können. Mit den Enterprise Editions der IDEs wie Borland JBuilder, Oracle JDeveloper, IBM WebSphere Studio, Eclipse, BEA WebLogic Studio, Sun ONE Studio, etc. können Sie beispielsweise Haltepunkte setzen, Methodenaufrufe verfolgen und so weiter. Manche IDEs ermöglichen es sogar, eine Verbindung zu einem Server herzustellen, der auf einem Remote-System ausgeführt wird.
Praktikum Datenbanksysteme. Ho Ngoc Duc IFIS Universität zu Lübeck 28.05.2003
Praktikum Datenbanksysteme Ho Ngoc Duc IFIS Universität zu Lübeck 28.05.2003 Nullwerte und Primitive Typen Wenn parent==null, was wird in der Datenbank gespeichert? Wenn man aus der DB liest, wie kann
MehrPraktikum Datenbanksysteme. Ho Ngoc Duc IFIS - Universität zu Lübeck 01.06.2005
Praktikum Datenbanksysteme Ho Ngoc Duc IFIS - Universität zu Lübeck 01.06.2005 Tomcat-Installation $JAVA_HOME (z.b. /home/dbp00/j2sdk1.4.2) $CATALINA_HOME (/home/dbp00/jakarta-tomcat-4) Skripte zum Start/Stop:
Mehr4 Aufzählungen und Listen erstellen
4 4 Aufzählungen und Listen erstellen Beim Strukturieren von Dokumenten und Inhalten stellen Listen und Aufzählungen wichtige Werkzeuge dar. Mit ihnen lässt sich so ziemlich alles sortieren, was auf einer
MehrMCRServlet Table of contents
Table of contents 1 Das Zusammenspiel der Servlets mit dem MCRServlet... 2 1 Das Zusammenspiel der Servlets mit dem MCRServlet Als übergeordnetes Servlet mit einigen grundlegenden Funktionalitäten dient
MehrZwischenablage (Bilder, Texte,...)
Zwischenablage was ist das? Informationen über. die Bedeutung der Windows-Zwischenablage Kopieren und Einfügen mit der Zwischenablage Vermeiden von Fehlern beim Arbeiten mit der Zwischenablage Bei diesen
MehrStundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten
Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten 2008 netcadservice GmbH netcadservice GmbH Augustinerstraße 3 D-83395 Freilassing Dieses Programm ist urheberrechtlich geschützt. Eine Weitergabe
MehrMedea3 Print-Client (m3_print)
Medea3 Print-Client (m3_print) Installationsanleitung Installationsanleitung m3_print.exe...2 1. Installieren von Ghostskript und Ghostview...2 1. Ghostskript...2 2. Ghostview...3 2. Kopieren des Print-Client-Programms...6
MehrObjektorientierte Programmierung
Objektorientierte Programmierung 1 Geschichte Dahl, Nygaard: Simula 67 (Algol 60 + Objektorientierung) Kay et al.: Smalltalk (erste rein-objektorientierte Sprache) Object Pascal, Objective C, C++ (wiederum
MehrWindows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1
Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1 Wenn der Name nicht gerade www.buch.de oder www.bmw.de heißt, sind Internetadressen oft schwer zu merken Deshalb ist es sinnvoll, die Adressen
MehrEnigmail Konfiguration
Enigmail Konfiguration 11.06.2006 Steffen.Teubner@Arcor.de Enigmail ist in der Grundkonfiguration so eingestellt, dass alles funktioniert ohne weitere Einstellungen vornehmen zu müssen. Für alle, die es
MehrGEONET Anleitung für Web-Autoren
GEONET Anleitung für Web-Autoren Alfred Wassermann Universität Bayreuth Alfred.Wassermann@uni-bayreuth.de 5. Mai 1999 Inhaltsverzeichnis 1 Technische Voraussetzungen 1 2 JAVA-Programme in HTML-Seiten verwenden
MehrMenü Macro. WinIBW2-Macros unter Windows7? Macros aufnehmen
Menü Macro WinIBW2-Macros unter Windows7?... 1 Macros aufnehmen... 1 Menübefehle und Schaltflächen in Macros verwenden... 4 Macros bearbeiten... 4 Macros löschen... 5 Macro-Dateien... 5 Macros importieren...
MehrDELFI. Benutzeranleitung Dateiversand für unsere Kunden. Grontmij GmbH. Postfach 34 70 17 28339 Bremen. Friedrich-Mißler-Straße 42 28211 Bremen
Grontmij GmbH Postfach 34 70 17 28339 Bremen Friedrich-Mißler-Straße 42 28211 Bremen T +49 421 2032-6 F +49 421 2032-747 E info@grontmij.de W www.grontmij.de DELFI Benutzeranleitung Dateiversand für unsere
MehrThunderbird herunterladen, Installieren und einrichten Version 31.3.0 (portable)
Thunderbird herunterladen, Installieren und einrichten Version 31.3.0 (portable) Thunderbird ist ein quelloffenes E-Mail-Programm (manchmal auch Client genannt), das leicht herunterzuladen und zu installieren
MehrDateimanagement in Moodle Eine Schritt-für
Übersicht: Lehrende können Dateien in einen Moodle-Kurs hochladen, in Verzeichnissen verwalten und für Studierende zugänglich machen. Jeder Moodle-Kurs hat einen Hauptordner Dateien im Administrationsblock.
MehrDokumentation. Black- und Whitelists. Absenderadressen auf eine Blacklist oder eine Whitelist setzen. Zugriff per Webbrowser
Dokumentation Black- und Whitelists Absenderadressen auf eine Blacklist oder eine Whitelist setzen. Zugriff per Webbrowser Inhalt INHALT 1 Kategorie Black- und Whitelists... 2 1.1 Was sind Black- und Whitelists?...
MehrHandbuch Fischertechnik-Einzelteiltabelle V3.7.3
Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 von Markus Mack Stand: Samstag, 17. April 2004 Inhaltsverzeichnis 1. Systemvorraussetzungen...3 2. Installation und Start...3 3. Anpassen der Tabelle...3
MehrTutorial - www.root13.de
Tutorial - www.root13.de Netzwerk unter Linux einrichten (SuSE 7.0 oder höher) Inhaltsverzeichnis: - Netzwerk einrichten - Apache einrichten - einfaches FTP einrichten - GRUB einrichten Seite 1 Netzwerk
MehrASA Schnittstelle zu Endian Firewall Hotspot aktivieren. Konfiguration ASA jhotel
ENDIAN DISTRIBUTOR ASA Schnittstelle zu Endian Firewall Hotspot aktivieren Konfiguration ASA jhotel ASA jhotel öffnen Unter den Menüpunkt Einrichtung System System Dort auf Betrieb Kommunikation Internet-Zugang
MehrIst Excel das richtige Tool für FMEA? Steve Murphy, Marc Schaeffers
Ist Excel das richtige Tool für FMEA? Steve Murphy, Marc Schaeffers Ist Excel das richtige Tool für FMEA? Einleitung Wenn in einem Unternehmen FMEA eingeführt wird, fangen die meisten sofort damit an,
MehrKennen, können, beherrschen lernen was gebraucht wird www.doelle-web.de
Inhaltsverzeichnis Inhaltsverzeichnis... 1 Grundlagen... 2 Hyperlinks innerhalb einer Datei... 2 Verweisziel definieren... 2 Einen Querverweis setzen... 3 Verschiedene Arten von Hyperlinks... 3 Einfache
MehrAufklappelemente anlegen
Aufklappelemente anlegen Dieses Dokument beschreibt die grundsätzliche Erstellung der Aufklappelemente in der mittleren und rechten Spalte. Login Melden Sie sich an der jeweiligen Website an, in dem Sie
MehrAnton Ochsenkühn. amac BUCH VERLAG. Ecxel 2016. für Mac. amac-buch Verlag
Anton Ochsenkühn amac BUCH VERLAG Ecxel 2016 für Mac amac-buch Verlag 2 Word-Dokumentenkatalog! Zudem können unterhalb von Neu noch Zuletzt verwendet eingeblendet werden. Damit hat der Anwender einen sehr
MehrMediator 9 - Lernprogramm
Mediator 9 - Lernprogramm Ein Lernprogramm mit Mediator erstellen Mediator 9 bietet viele Möglichkeiten, CBT-Module (Computer Based Training = Computerunterstütztes Lernen) zu erstellen, z. B. Drag & Drop
MehrProfessionelle Seminare im Bereich MS-Office
Serienbrief aus Outlook heraus Schritt 1 Zuerst sollten Sie die Kontakte einblenden, damit Ihnen der Seriendruck zur Verfügung steht. Schritt 2 Danach wählen Sie bitte Gerhard Grünholz 1 Schritt 3 Es öffnet
MehrEinführung in die Programmierung
Technische Universität München WS 2003/2004 Institut für Informatik Prof. Dr. Christoph Zenger Testklausur Einführung in die Programmierung Probeklausur Java (Lösungsvorschlag) 1 Die Klasse ArrayList In
MehrInformationen zur Verwendung von Visual Studio und cmake
Inhaltsverzeichnis Informationen zur Verwendung von Visual Studio und cmake... 2 Erste Schritte mit Visual Studio... 2 Einstellungen für Visual Studio 2013... 2 Nutzung von cmake... 6 Installation von
MehrWEBSEITEN ENTWICKELN MIT ASP.NET
jamal BAYDAOUI WEBSEITEN ENTWICKELN MIT ASP.NET EINE EINFÜHRUNG MIT UMFANGREICHEM BEISPIELPROJEKT ALLE CODES IN VISUAL BASIC UND C# 3.2 Installation 11 Bild 3.2 Der Webplattform-Installer Bild 3.3 IDE-Startbildschirm
MehrDaten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen
Daten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen Inhalt 1. Die Funambol Software... 3 2. Download und Installation... 3 3.
MehrL10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016
L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 Referentin: Dr. Kelly Neudorfer Universität Hohenheim Was wir jetzt besprechen werden ist eine Frage, mit denen viele
MehrLogics App-Designer V3.1 Schnellstart
Logics App-Designer V3.1 Schnellstart Stand 2012-09-07 Logics Software GmbH Tel: +49/89/552404-0 Schwanthalerstraße 9 http://www.logics.de/apps D-80336 München mailto:apps@logics.de Inhalt Ihr Logics Zugang...
Mehr5 DATEN. 5.1. Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu
Daten Makro + VBA effektiv 5 DATEN 5.1. Variablen Variablen können beliebige Werte zugewiesen und im Gegensatz zu Konstanten jederzeit im Programm verändert werden. Als Variablen können beliebige Zeichenketten
MehrLineargleichungssysteme: Additions-/ Subtraktionsverfahren
Lineargleichungssysteme: Additions-/ Subtraktionsverfahren W. Kippels 22. Februar 2014 Inhaltsverzeichnis 1 Einleitung 2 2 Lineargleichungssysteme zweiten Grades 2 3 Lineargleichungssysteme höheren als
MehrDatenbank-Verschlüsselung mit DbDefence und Webanwendungen.
Datenbank-Verschlüsselung mit DbDefence und Webanwendungen. In diesem Artikel werden wir Ihnen zeigen, wie Sie eine Datenbank verschlüsseln können, um den Zugriff einzuschränken, aber trotzdem noch eine
MehrDatenbanken Kapitel 2
Datenbanken Kapitel 2 1 Eine existierende Datenbank öffnen Eine Datenbank, die mit Microsoft Access erschaffen wurde, kann mit dem gleichen Programm auch wieder geladen werden: Die einfachste Methode ist,
MehrFlashfragen in ILIAS Test & Assessment. Helmut Schottmüller
Flashfragen in ILIAS Test & Assessment Helmut Schottmüller Flashfragen in ILIAS Test & Assessment Helmut Schottmüller Veröffentlicht Januar 2009 Copyright 2009 Helmut Schottmüller Inhaltsverzeichnis 1.
MehrCMS.R. Bedienungsanleitung. Modul Cron. Copyright 10.09.2009. www.sruttloff.de CMS.R. - 1 - Revision 1
CMS.R. Bedienungsanleitung Modul Cron Revision 1 Copyright 10.09.2009 www.sruttloff.de CMS.R. - 1 - WOZU CRON...3 VERWENDUNG...3 EINSTELLUNGEN...5 TASK ERSTELLEN / BEARBEITEN...6 RECHTE...7 EREIGNISSE...7
MehrAutoCAD 2007 - Dienstprogramm zur Lizenzübertragung
AutoCAD 2007 - Dienstprogramm zur Lizenzübertragung Problem: Um AutoCAD abwechselnd auf mehreren Rechnern einsetzen zu können konnte man bis AutoCAD 2000 einfach den Dongle umstecken. Seit AutoCAD 2000i
MehrStep by Step Webserver unter Windows Server 2003. von Christian Bartl
Step by Step Webserver unter Windows Server 2003 von Webserver unter Windows Server 2003 Um den WWW-Server-Dienst IIS (Internet Information Service) zu nutzen muss dieser zunächst installiert werden (wird
MehrInstallation / Update für die P aketdatenbank 1.x (Version 3-23.06.2012)
Installation / Update für die P aketdatenbank 1.x (Version 3-23.06.2012) Um Auswertungen mit BIRT vornehmen zu können, wird die "BIRT ReportEngine" benötigt. Diese ist in der "Foconis Paketdatenbank 1.0.2"
MehrVersion smarter mobile(zu finden unter Einstellungen, Siehe Bild) : Gerät/Typ(z.B. Panasonic Toughbook, Ipad Air, Handy Samsung S1):
Supportanfrage ESN Bitte füllen Sie zu jeder Supportanfrage diese Vorlage aus. Sie helfen uns damit, Ihre Anfrage kompetent und schnell beantworten zu können. Verwenden Sie für jedes einzelne Thema jeweils
MehrVollversion: http://vereine.kot-dreisbe.de
Vollversion: Im Startfenster bekommen Sie alle Termina angezeigt, die in der Datenbank aufgenommen sind. Diese können nach den orange gekennzeichneten Titeln sortiert werden. (siehe oben: Verein, Priorität)
MehrDreamweaver 8 Einführung
Dreamweaver 8 Einführung Die Oberfläche von Dreamweaver Beim Start von Dreamweaver 8 präsentiert sich das Programm mit der folgenden Oberfläche: Menüleiste mit allen verfügbaren Befehlen von Dreamweaver.
MehrUMSTELLUNG DER RÖNTGEN-SCHNITTSTELLE DÜRR-DBSWIN AUF DÜRR-VDDS
UMSTELLUNG DER RÖNTGEN-SCHNITTSTELLE DÜRR-DBSWIN AUF DÜRR-VDDS Pionier der Zahnarzt-Software. Seit 1986. 1 Seite 1/5 Diese Anleitung soll Ihnen dabei helfen, eine bestehende DBSWIN-Anbindung über den Patientendatenexport
MehrDiese Anleitung wurde erstellt von Niclas Lüchau und Daniel Scherer. Erste Anmeldung. Schritt 1: Anmeldung..2. Schritt 2: Passwort setzen 3
Diese Anleitung wurde erstellt von Niclas Lüchau und Daniel Scherer Inhalt Erste Anmeldung. Schritt 1: Anmeldung..2 Schritt 2: Passwort setzen 3 Schritt 3: Nachträgliches Ändern des Passworts..4 Schreiben
MehrDrucken aus der Anwendung
Drucken aus der Anwendung Drucken aus der Anwendung Nicht jeder Großformatdruck benötigt die volle Funktionsvielfalt von PosterJet - häufig sind es Standarddrucke wie Flussdiagramme und Organigramme die
MehrInventarverwaltung mit Access 2007/10
Inventarverwaltung mit Access 2007/10 Version 1.0 kostenlose Vollversion Autor: sbduss Beat Duss Schweiz http://www.sbduss.com letzte Änderung 21.06.2015 Inhaltsverzeichnis Installation... 3 Hauptfenster...
Mehri n g e n i e u r b ü r o f ü r s o f t w a r e t e c h n o l o g i e w w w. v o e l t e r. d e Servlet Debugging
Servlet Debugging Markus Völter, voelter@acm.org, www.voelter.de Bei der Arbeit mit Servlets kommt man recht schnell an den Punkt, an dem man Servlets vernünftig testen oder debuggen will. Mit Hilfe des
MehrStammdatenanlage über den Einrichtungsassistenten
Stammdatenanlage über den Einrichtungsassistenten Schritt für Schritt zur fertig eingerichteten Hotelverwaltung mit dem Einrichtungsassistenten Bitte bereiten Sie sich, bevor Sie starten, mit der Checkliste
MehrTipps und Tricks zu den Updates
Tipps und Tricks zu den Updates Grundsätzlich können Sie Updates immer auf 2 Wegen herunterladen, zum einen direkt über unsere Internetseite, zum anderen aus unserer email zu einem aktuellen Update. Wenn
Mehr1. Adressen für den Serienversand (Briefe Katalogdruck Werbung/Anfrage ) auswählen. Die Auswahl kann gespeichert werden.
Der Serienversand Was kann man mit der Maske Serienversand machen? 1. Adressen für den Serienversand (Briefe Katalogdruck Werbung/Anfrage ) auswählen. Die Auswahl kann gespeichert werden. 2. Adressen auswählen,
MehrPunkt 1 bis 11: -Anmeldung bei Schlecker und 1-8 -Herunterladen der Software
Wie erzeugt man ein Fotobuch im Internet bei Schlecker Seite Punkt 1 bis 11: -Anmeldung bei Schlecker und 1-8 -Herunterladen der Software Punkt 12 bis 24: -Wir arbeiten mit der Software 8-16 -Erstellung
MehrWindows 8.1. Grundkurs kompakt. Markus Krimm, Peter Wies 1. Ausgabe, Januar 2014. inkl. zusätzlichem Übungsanhang K-W81-G-UA
Markus Krimm, Peter Wies 1. Ausgabe, Januar 2014 Windows 8.1 Grundkurs kompakt inkl. zusätzlichem Übungsanhang K-W81-G-UA 1.3 Der Startbildschirm Der erste Blick auf den Startbildschirm (Startseite) Nach
MehrOutlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang
sysplus.ch outlook - mail-grundlagen Seite 1/8 Outlook Mail-Grundlagen Posteingang Es gibt verschiedene Möglichkeiten, um zum Posteingang zu gelangen. Man kann links im Outlook-Fenster auf die Schaltfläche
MehrOP-LOG www.op-log.de
Verwendung von Microsoft SQL Server, Seite 1/18 OP-LOG www.op-log.de Anleitung: Verwendung von Microsoft SQL Server 2005 Stand Mai 2010 1 Ich-lese-keine-Anleitungen 'Verwendung von Microsoft SQL Server
MehrGruppenrichtlinien und Softwareverteilung
Gruppenrichtlinien und Softwareverteilung Ergänzungen zur Musterlösung Bitte lesen Sie zuerst die gesamte Anleitung durch! Vorbemerkung: Die Begriffe OU (Organizational Unit) und Raum werden in der folgenden
MehrWordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten
Wordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten Version 1.0 Wordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten In unserer Anleitung zeigen wir Dir, wie Du Blogbeiträge
MehrLDAP Konfiguration nach einem Update auf Version 6.3 Version 1.2 Stand: 23. Januar 2012 Copyright MATESO GmbH
LDAP Konfiguration nach einem Update auf Version 6.3 Version 1.2 Stand: 23. Januar 2012 Copyright MATESO GmbH MATESO GmbH Daimlerstraße 7 86368 Gersthofen www.mateso.de Dieses Dokument beschreibt die Konfiguration
MehrDas Handbuch zu Simond. Peter H. Grasch
Peter H. Grasch 2 Inhaltsverzeichnis 1 Einführung 6 2 Simond verwenden 7 2.1 Benutzereinrichtung.................................... 7 2.2 Netzwerkeinrichtung.................................... 9 2.3
MehrObjektorientierte Programmierung. Kapitel 12: Interfaces
12. Interfaces 1/14 Objektorientierte Programmierung Kapitel 12: Interfaces Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester 2012/13 http://www.informatik.uni-halle.de/ brass/oop12/
MehrNutzung von GiS BasePac 8 im Netzwerk
Allgemeines Grundsätzlich kann das GiS BasePac Programm in allen Netzwerken eingesetzt werden, die Verbindungen als Laufwerk zu lassen (alle WINDOWS Versionen). Die GiS Software unterstützt nur den Zugriff
MehrSpeicher in der Cloud
Speicher in der Cloud Kostenbremse, Sicherheitsrisiko oder Basis für die unternehmensweite Kollaboration? von Cornelius Höchel-Winter 2013 ComConsult Research GmbH, Aachen 3 SYNCHRONISATION TEUFELSZEUG
Mehr3 Installation von Exchange
3 Installation von Exchange Server 2010 In diesem Kapitel wird nun der erste Exchange Server 2010 in eine neue Umgebung installiert. Ich werde hier erst einmal eine einfache Installation mit der grafischen
MehrEr musste so eingerichtet werden, dass das D-Laufwerk auf das E-Laufwerk gespiegelt
Inhaltsverzeichnis Aufgabe... 1 Allgemein... 1 Active Directory... 1 Konfiguration... 2 Benutzer erstellen... 3 Eigenes Verzeichnis erstellen... 3 Benutzerkonto erstellen... 3 Profil einrichten... 5 Berechtigungen
MehrCOMPUTERIA VOM 25.2.15 SERIENBRIEFE UND ETIKETTENDRUCK
COMPUTERIA VOM 25.2.15 SERIENBRIEFE UND ETIKETTENDRUCK WAS SIND SERIENBRIEFE? Bei einem Serienbrief handelt es sich um eine Art Word Vorlage, bei der das gleiche Dokument mehrmals gedruckt werden muss,
MehrErstellen von x-y-diagrammen in OpenOffice.calc
Erstellen von x-y-diagrammen in OpenOffice.calc In dieser kleinen Anleitung geht es nur darum, aus einer bestehenden Tabelle ein x-y-diagramm zu erzeugen. D.h. es müssen in der Tabelle mindestens zwei
MehrBedienungsanleitung Anrufbeantworter für digitale Telefone Alcatel 4039
Bedienungsanleitung Anrufbeantworter für digitale Telefone Alcatel 4039 Inhaltsverzeichnis Version 09/10 1 Einleitung 3 2 Erstaktivierung des Anrufbeantworters 5 2.1 Erläuterungen der einzelnen Schritte
MehrAnleitung für die Formularbearbeitung
1 Allgemeines Anleitung für die Formularbearbeitung Die hier hinterlegten Formulare sind mit der Version Adobe Acrobat 7.0 erstellt worden und im Adobe-PDF Format angelegt. Damit alle hinterlegten Funktionen
Mehr.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage
.htaccess HOWTO zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage Stand: 21.06.2015 Inhaltsverzeichnis 1. Vorwort...3 2. Verwendung...4 2.1 Allgemeines...4 2.1 Das Aussehen der.htaccess
MehrAGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom 21.10.2013b
AGROPLUS Buchhaltung Daten-Server und Sicherheitskopie Version vom 21.10.2013b 3a) Der Daten-Server Modus und der Tresor Der Daten-Server ist eine Betriebsart welche dem Nutzer eine grosse Flexibilität
MehrHandbuch für Redakteure
Handbuch für Redakteure Erste Schritte... 1 Artikel erstellen... 2 Artikelinhalt bearbeiten... 3 Artikel bearbeiten... 3 Grunddaten ändern... 5 Weitere Artikeleigenschaften... 5 Der WYSIWYG-Editor... 6
MehrVerwalten und Organisieren von Fotos,
Verwalten und Organisieren von Fotos, Datensicherung auf einen externen Datenträger durchführen, Datensicherung auf externe Datenträger - Datensicherheit Grundsätze 02 - Sicherungsmethode / FreeCommander
MehrDer SAP BW-BPS Web Interface Builder
Der SAP BW-BPS Web Interface Builder Projekt: elearning SAP BPS Auftraggeber: Prof. Dr. Jörg Courant Gruppe 3: Bearbeiter: Diana Krebs Stefan Henneicke Uwe Jänsch Andy Renner Daniel Fraede Uwe Jänsch 1
MehrFuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7
FuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7 Die Installation der FuxMedia Software erfolgt erst NACH Einrichtung des Netzlaufwerks! Menüleiste einblenden, falls nicht vorhanden Die
MehrAnleitung über den Umgang mit Schildern
Anleitung über den Umgang mit Schildern -Vorwort -Wo bekommt man Schilder? -Wo und wie speichert man die Schilder? -Wie füge ich die Schilder in meinen Track ein? -Welche Bauteile kann man noch für Schilder
MehrProgrammieren in Java
Programmieren in Java objektorientierte Programmierung 2 2 Zusammenhang Klasse-Datei In jeder *.java Datei kann es genau eine public-klasse geben wobei Klassen- und Dateiname übereinstimmen. Es können
MehrTreppensoftware Programme. Hilfe - 3D Plus Online. konstruieren/präsentieren
Treppensoftware Programme Hilfe - 3D Plus Online konstruieren/präsentieren INHALT 1. Allgemeines... 3 2. Arbeitsbereich im Internet aufrufen... 4 3. Firmendaten im Internet hinterlegen... 5 4. Verwaltung
MehrDatenaufbereitung in SPSS. Daten zusammenfügen
Daten zusammenfügen I. Fälle hinzufügen Diese Schritte müssen Sie unternehmen, wenn die Daten in unterschiedlichen Dateien sind; wenn also die Daten von unterschiedlichen Personen in unterschiedlichen
MehrSeite 1 von 14. Cookie-Einstellungen verschiedener Browser
Seite 1 von 14 Cookie-Einstellungen verschiedener Browser Cookie-Einstellungen verschiedener Browser, 7. Dezember 2015 Inhaltsverzeichnis 1.Aktivierung von Cookies... 3 2.Cookies... 3 2.1.Wofu r braucht
MehrKurzanleitung fu r Clubbeauftragte zur Pflege der Mitgliederdaten im Mitgliederbereich
Kurzanleitung fu r Clubbeauftragte zur Pflege der Mitgliederdaten im Mitgliederbereich Mitgliederbereich (Version 1.0) Bitte loggen Sie sich in den Mitgliederbereich mit den Ihnen bekannten Zugangsdaten
MehrUm in das Administrationsmenü zu gelangen ruft Ihr Eure Seite auf mit dem Zusatz?mod=admin :
WebsoziCMS 2.8.9 Kurzanleitung Stand: 10.04.2008 Andreas Kesting Diese Kurzanleitung zum WebsoziCMS 2.8.9 beschränkt beschränkt sich auf die häufigsten Tätigkeiten beim Administrieren Eurer Homepage: -
MehrBenutzerhandbuch - Elterliche Kontrolle
Benutzerhandbuch - Elterliche Kontrolle Verzeichnis Was ist die mymaga-startseite? 1. erste Anmeldung - Administrator 2. schnittstelle 2.1 Administrator - Hautbildschirm 2.2 Administrator - rechtes Menü
Mehr1 Einleitung. Lernziele. automatische Antworten bei Abwesenheit senden. Einstellungen für automatische Antworten Lerndauer. 4 Minuten.
1 Einleitung Lernziele automatische Antworten bei Abwesenheit senden Einstellungen für automatische Antworten Lerndauer 4 Minuten Seite 1 von 18 2 Antworten bei Abwesenheit senden» Outlook kann während
Mehr1. Aktionen-Palette durch "Fenster /Aktionen ALT+F9" öffnen. 2. Anlegen eines neuen Set über "Neues Set..." (über das kleine Dreieck zu erreichen)
Tipp: Aktionen (c) 2005 Thomas Stölting, Stand: 25.4. 2005 In Photoshop werden häufig immer wieder die gleichen Befehlssequenzen benötigt. Um sie nicht jedesmal manuell neu eingeben zu müssen, können diese
MehrSysteme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss
Systeme 1 Kapitel 6 Nebenläufigkeit und wechselseitiger Ausschluss Threads Die Adressräume verschiedener Prozesse sind getrennt und geschützt gegen den Zugriff anderer Prozesse. Threads sind leichtgewichtige
MehrProgramme im Griff Was bringt Ihnen dieses Kapitel?
3-8272-5838-3 Windows Me 2 Programme im Griff Was bringt Ihnen dieses Kapitel? Wenn Sie unter Windows arbeiten (z.b. einen Brief schreiben, etwas ausdrucken oder ein Fenster öffnen), steckt letztendlich
MehrIhr Benutzerhandbuch SAMSUNG SGH-V200 http://de.yourpdfguides.com/dref/459178
Lesen Sie die Empfehlungen in der Anleitung, dem technischen Handbuch oder der Installationsanleitung für SAMSUNG SGH- V200. Hier finden Sie die Antworten auf alle Ihre Fragen über die in der Bedienungsanleitung
MehrNovell Client. Anleitung. zur Verfügung gestellt durch: ZID Dezentrale Systeme. Februar 2015. ZID Dezentrale Systeme
Novell Client Anleitung zur Verfügung gestellt durch: ZID Dezentrale Systeme Februar 2015 Seite 2 von 8 Mit der Einführung von Windows 7 hat sich die Novell-Anmeldung sehr stark verändert. Der Novell Client
MehrHilfedatei der Oden$-Börse Stand Juni 2014
Hilfedatei der Oden$-Börse Stand Juni 2014 Inhalt 1. Einleitung... 2 2. Die Anmeldung... 2 2.1 Die Erstregistrierung... 3 2.2 Die Mitgliedsnummer anfordern... 4 3. Die Funktionen für Nutzer... 5 3.1 Arbeiten
MehrWie kann ich meine Daten importieren? Wie kann ich meine Profile verwalten?
Administration: Wie kann ich meine Daten importieren? Wie kann ich meine Profile verwalten? Wie kann ich von «Einzelgesellschaft» zu «Mehrere Gesellschaften» wechseln? Gebrauch Wie kann ich einen Arbeitnehmer
MehrDokumentation IBIS Monitor
Dokumentation IBIS Monitor Seite 1 von 16 11.01.06 Inhaltsverzeichnis 1. Allgemein 2. Installation und Programm starten 3. Programmkonfiguration 4. Aufzeichnung 4.1 Aufzeichnung mitschneiden 4.1.1 Inhalt
MehrDokumentation. Serienbriefe mit Galileo-Daten im Word erstellen
Dokumentation Serienbriefe mit Galileo-Daten im Word erstellen K:\Dokumentationen\Galileo bibwin Kunden Dokus\Kurz-Doku Seriendruck.doc 04.03.2008 1 Ablauf...2 2 Kundenadressen...3 3 Datenexport...4 3.1
MehrErfolgsmeldungen im Praxisbetrieb
Inhalt 1. Was ist KV-Connect... 1 a. KV-SafeNet... 1 b. KV-Connect... 1 2. Vorbereitung der Installation... 2 a. KV-Connect-Zugangsdaten... 2 3. Einrichtung von KV-Connect... 3 a. Einstellungen im Programm...
Mehr4.1 Wie bediene ich das Webportal?
4.1 Wie bediene ich das Webportal? Die Bedienung ist durch ein Redaktionssystem sehr einfach möglich. Das Tutorial zeigt Ihnen wie Sie SMS-News und Top-News erstellen und veröffentlichen können. Schritt
MehrInformationen zum neuen Studmail häufige Fragen
1 Stand: 15.01.2013 Informationen zum neuen Studmail häufige Fragen (Dokument wird bei Bedarf laufend erweitert) Problem: Einloggen funktioniert, aber der Browser lädt dann ewig und zeigt nichts an Lösung:
MehrWir arbeiten mit Zufallszahlen
Abb. 1: Bei Kartenspielen müssen zu Beginn die Karten zufällig ausgeteilt werden. Wir arbeiten mit Zufallszahlen Jedesmal wenn ein neues Patience-Spiel gestartet wird, muss das Computerprogramm die Karten
MehrHilfen zur Verwendung der Word-Dokumentvorlage des BIS-Verlags
Hilfen zur Verwendung der Word-Dokumentvorlage des BIS-Verlags 2013 style_sheet_bis_verlag_20130513 Arbeiten mit der Dokumentvorlage des BIS-Verlags... 3 Dokumentvorlage Wofür?... 3 Wohin mit der Dokumentvorlage...
MehrDer lokale und verteilte Fall
Lokale Beans Der lokale und verteilte Fall RemoteClient Lokaler Client (JSP) RemoteSession/Entity-Bean Lokale Session/Entity-Bean 2 Lokale Beans Die bisher vorgestellten EJBswaren immer in der Lage auf
MehrHANDBUCH PHOENIX II - DOKUMENTENVERWALTUNG
it4sport GmbH HANDBUCH PHOENIX II - DOKUMENTENVERWALTUNG Stand 10.07.2014 Version 2.0 1. INHALTSVERZEICHNIS 2. Abbildungsverzeichnis... 3 3. Dokumentenumfang... 4 4. Dokumente anzeigen... 5 4.1 Dokumente
MehrPrimzahlen und RSA-Verschlüsselung
Primzahlen und RSA-Verschlüsselung Michael Fütterer und Jonathan Zachhuber 1 Einiges zu Primzahlen Ein paar Definitionen: Wir bezeichnen mit Z die Menge der positiven und negativen ganzen Zahlen, also
Mehr