<jsptutorial />

Client-Anfragen


Einleitung

Webauftritte sind heutzutage nicht mehr denkbar, ohne dass die Besucherin spezifische Anfragen stellen kann. Ob dies nur ein einfaches Kontakt-Formular ist oder ob es sich dabei um komplexere, mehrere Seiten überspannende Nutzer-Interaktionen handelt, überall werden Daten von der Nutzerin zum Server gesendet, und die Nutzerin erwartet, dass entsprechend geeignete Aktionen ausgelöst werden.
Wie im Anhang I: HTTP-Grundlagen beschrieben, werden von einem Browser sowohl die eigentlichen Daten, die die Nutzerin eingegeben hat, übertragen als auch zusätzliche Header-Daten, wie bspw. Cookies oder die Spracheinstellungen des Browsers. In den folgenden beiden Unterkapiteln werden wir sehen, wie auf diese Daten mittels Java in Servlets und JSPs zugegriffen werden kann.

Zum SeitenanfangZum Seitenanfang

Formulardaten

Da als eine Demo-Anwendung im Tutorial ein Web-Mailer erstellt wird, verwenden wir hier als Beispiel ein (sehr simples) Formular zum Schreiben und Adressieren von E-Mails. Der folgende Screenshot zeigt, wie das Formular im Browser aussieht.
screen_mailformular.png
Der HTML-Code, in denen das Formular definiert wird, sieht wie folgt aus:

<!--
   CSS inspired by Christopher Schmitt's excellent book:
   CSS cookbook
   O'Reilly
   Sebastopol(CA, USA), 2004

   the css-file can be found at:
   http://www.jsptutorial.org/examples/mailer.css
-->
<html>
<head>
   <link rel="stylesheet" type="text/css" href="mailer.css" />
</head>
<body>

<form method="POST">
   <label for="mailSender">Sender</label>
   <input type="text" id="mailSender" name="mailSender" />
   <br/>
   <label for="mailRecipient">Recipient</label>
   <input type="text" id="mailRecipient" name="mailRecipient" />
   <br/>
   <label for="mailSubject">Subject</label>
   <input type="text" id="mailSubject" name="mailSubject" />
   <br/>
   <label for="mailText">Mailtext</label>
   <textarea name="mailText" id="mailText" class="sendForm">
   </textarea>
   <br/>
   <input type="submit" class="submitButton" value="Ok" />
</form>
</body>
</html>

Zu beachten ist hierbei, dass alle Formularelemente einen Namen haben (bspw. "mailSender"). Dieser Name ist entscheidend für das spätere Auslesen der Werte. Dabei ist die Groß/Kleinschreibung im Unterschied zu den später besprochenen HTTP-Header-Daten unbedingt korrekt beizubehalten.
Im Anhang I: HTTP-Grundlagen wurde bereits beschrieben, wie die Daten vom Client (dem Browser)1 zum Server übertragen werden. Und aus dem Servlet-Kapitel (s. Anhang II: Servlets - Die Grundlagen) wissen wir bereits, dass sich alle Informationen zur Client-Anfrage in einem HttpServletRequest-Objekt befinden. Dieses existiert in der JSP als das implizite Objekt "request" (s. Kapitel Implizite Objekte) und wird im Servlet der "service()", bzw. den entsprechenden Handler-Methoden "doXXX()" als Parameter übergeben. Dieses Objekt verfügt über drei Methoden, um Formular-Daten bzw. Parameter auszulesen: "getParameter(String)", "getParameterValues(String)" und "getParameterNames()". Übrigens sind die Methoden Bestandteil des Interfaces ServletRequest. Da HttpServletRequest davon erbt, stehen sie dort natürlich auch zur Verfügung.

getParameter(String)

Mit "getParameter(String)" liest man einen einzelnen Parameter eines Formulares aus. Der übergebene String muss dabei exakt dem Namen entsprechen, den man dem Attribut "name" des entsprechenden Formular-Elementes gegeben hat. Wie erwähnt, ist hierbei die Groß-/Kleinschreibung unbedingt zu beachten.
Die Methode "getParameter(String)" ist die geeignete, um bspw. Werte aus Text-Feldern oder von RadioButton-Gruppen auszulesen (s. dazu das Beispiel). Völlig ungeeignet ist diese Methode für Formulardaten, bei denen mehrere Daten mit dem gleichen Namen gesendet werden (bspw. Auswahllisten mit Mehrfachauswahl oder mehrere Checkboxen mit gleichem "name"-Attribut). Bei diesen wird hier nur der erste Wert zurückgegeben. Um alle auszulesen, ist die im Folgenden beschriebene Methode "getParameterValues(String)" zu verwenden.
Bei "getParameter(String)" wird immer ein String zurückgegeben. Dies gilt auch bei Radio-Buttons, bei denen "true" oder "false" als String zurückgegeben wird. Hier muss man also von Hand konvertieren (so denn man nicht ohnehin eines der Web-Frameworks wie bspw. Struts, JSF oder Tapestry verwendet).
Der folgende Code-Abschnitt liest bspw. die Daten unseres Mail-Formulars aus und speichert sie in lokalen Variablen zwischen.
String recipient = request.getParameter("mailRecipient");
String mailSender = request.getParameter("mailSender");
String subject = request.getParameter("mailSubject");
String body = request.getParameter("mailText");

if (StringUtils.isEmpty(recipient)) {
   // some kind of error handling...
}

getParameterValues(String)

Diese Methode unterscheidet sich von der Methode "getParameter(String)" dadurch, dass immer ein Array vom Typ String[] zurückgeliefert wird. Dies funktioniert auch bei einfachen Textfeldern, wo dann ein Array mit genau einem Eintrag zurückgeliefert wird. In diesem Fall ist aber die zuvor vorgestellte Methode "getParameter(String)" geeigneter. Notwendig ist die Methode "getParameterValues(String)" überall dort, wo mehrere Werte mit dem gleichen Namen vom Browser übertragen werden können. Bei Gruppen gleich benannter Checkboxen ist dies bspw. unerlässlich. Das Array enthält bei so einer Checkbox-Gruppe dann alle selektierten Werte.

getParameterNames()

Mit "getParamterNames()" kann man sich eine Enumeration aller im Request enthaltenen Parameter holen. Diese Methode ist mitunter zum Debuggen ganz nützlich. Das folgende Beispiel zeigt die wohl häufigste Nutzung dieser Methode. hier werden einfach alle Parameter durchlaufen und ausgegeben.
// log all form-data
// logger is of type org.apache.log4j.Logger
if (logger.isDebugEnabled()) {
   Enumeration enumeration = request.getParameterNames();
   while (enumeration.hasMoreElements()) {
      String name = (String)enumeration.nextElement();
      logger.debug(name + " -> " + request.getHeader(name));
   }
}

getParameterMap()

Diese Methode ist eher ungewöhnlich. Sie gibt ein Objekt vom Typ Map zurück, wobei in dieser Map die name-Attribute der Formular-Felder als Keys vom Typ java.lang.String fungieren und deren Werte als Values - und zwar als ein String-Array. Also könnte man bspw. mit getParameterMap().get("mailSender")[0] den Wert der Absender-Email-Adresse aus dem Formular auslesen. Die Map ist für die Praxis weitestgehend unbedeutend, da die anderen Methoden nahezu immer besser geeignet sind. Es wundert daher auch nicht, dass diese Methode nicht Bestandteil der Sun Certified Web Component Developer-Prüfung ist.
In erster Linie lohnt sich die Methode dann, wenn alle Formulardaten in einer anderen Map untergebracht werden sollen, bspw. im Rahmen eines Frameworks. Dann reicht ein "targetMap.put(getParameterMap())" aus, um alle Formular-Parameter der Ziel-Map hinzuzufügen. Zudem kann man diese Methode natürlich ähnlich wie die Vorherige zum Debuggen nutzen.

Zum SeitenanfangZum Seitenanfang

HTTP-Header und Browser-Informationen

Wie im Kapitel Anhang I: HTTP-Grundlagen gezeigt, werden mit einer Anfrage nach einer bestimmten Ressource vom Browser zumeist noch zusätzliche Informationen an den Server mitgesendet. Diese geben bspw. Hinweise dazu, welche Datentypen der Browser überhaupt verarbeiten kann, welche Sprach-Präferenzen die Nutzerin eingestellt hat und vor allem, welchen Browser (User-Agent) die Nutzerin verwendet. Im folgenden Screenshot sieht man bspw., dass die Anfrage an die Seite "www.jsptutorial.org/newsletter.html" mit einem Mozilla-Browser unter Linux gestellt wurde und dass als bevorzugte Sprache zunächst Englisch, dann mit einer Präferenz von 0.8 Deutsch eingestellt ist2. Außerdem ist es dem Browser möglich, mit gzip komprimierte HTML-Seiten auszupacken3.
screen_gzipResponse.png
Doch wie wertet man diese Informationen aus? Die dazu notwendigen Methoden des HttpServletRequest-Objekt wurden schon im Kapitel "Implizite Objekte" aufgeführt, wo sich auch ein Beispiel findet, dass alle mitgelieferten Header ausliest und in einer Seite anzeigt.
In erster Linie sind die HTTP-Header vor allem für den Server interessant. So kann dieser eine Seite eben nur dann komprimieren, wenn er weiß, dass der Browser diese Komprimierung auch versteht (also den Header "Accept-Encoding: gzip" mitsendet). Ebenso werden Header-Informationen seitens des Servers genutzt, um bspw. dem Browser mitzuteilen, dass das Dokument in seinem Cache noch aktuell ist (Reaktion auf den Request-Header "If-Modified-Since"), oder um bei der Nutzung von HTTP 1.1 die Verbindung für einen angegeben Zeitraum offen zu halten.
Uns als Entwicklerinnen Java-basierter Webanwendungen interessieren hingegen v.a. drei Header. Zum einen der, welchen Browser die Nutzerin benutzt (Header "User-Agent") und zum zweiten die Angabe, welche Sprache bevorzugt wird (Header "Accept-Language"). Außerdem werden Cookies mittels HTTP-Header im Request an den Server übertragen, bzw. seitens des Servers "Set-Cookie"-Header zum Setzen von Cookies im Response gesendet. Cookies behandeln wir hier allerdings nicht. Dazu gibt es ein eigenes Kapitel (s. "Session-Handling, Cookies und URL-Rewriting").
Den User-Agent (also den Browser der Nutzerin) auszulesen, ist vermutlich die interessanteste Information. Der User-Agent gibt dabei Auskunft über den Browser, die Version des Browsers und auf welchem Betriebssystem dieser eingesetzt wird. Ein paar Beispiele aus unseren Logs:

BrowserUser-Agent-String
Firefox, Windows 98 Mozilla/5.0 (Windows; U; Win98; de-DE; rv:1.7.5) Gecko/20041108 Firefox/1.0
Firefox, Solaris Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7.6) Gecko/20050323 Firefox/1.0.2
IE, Mac OS X Mozilla/4.0 (compatible; MSIE 5.23; Mac_PowerPC)
IE, Windows NT Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)
Mozilla, Linux Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.7.11) Gecko/20050728
Mozilla, OS/2 Mozilla/5.0 (OS/2; U; Warp 4.5; de-AT; rv:1.4) Gecko/20030624
Mozilla, Windows XP Mozilla/5.0 (Windows; U; Windows NT 5.1; de-AT; rv:1.7.3) Gecko/20040910
Mozilla Camino, Mac OS X Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050427 Camino/0.8.4
Safari, Mac OS X Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/125.5.6 (KHTML, like Gecko) Safari/125.12
Opera, Windows XP Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.54 [de]
Konqueror, FreeBSD Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko)
Seamonkey, Linux Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.8) Gecko/20051219 SeaMonkey/1.0b


Eine deutlich ausführlichere Übersicht (und weitere Hinweise auf Englisch) unter http://en.wikipedia.org/wiki/User_agent. Auslesen können wir den User-Agent einfach mithilfe der folgenden Codezeile:

String userAgent = request.getHeader("User-Agent");

Mithilfe dieser Information könnte man dann bspw. eine serverseitige Browserweiche erstellen und dafür Sorge tragen, dass Nutzerinnen des Firefox andere CSS-Dateien erhalten als bspw. Nutzerinnen des Internet Explorer. Ebenso gilt dies für die unterschiedliche Unterstützung von JavaScript. Der Vorteil ist, dass der JavaScript und/oder CSS-Code für die jeweiligen Browser dadurch einfacher gehalten werden kann, wenn man auf dem Client nicht erst noch zwischen den verschiedenen Browsern unterscheiden muss.4
Eine weitere Möglichkeit, die Header sinnvoll zu nutzen, könnte sein, die Sprach-Präferenz der Nutzerin zu berücksichtigen. So könnte man auf der www.xyz.com-Seite automatisch zur www.xyz.de-Seite verzweigen, wenn man sieht, dass die Sprach-Präferenz auf Deutsch steht. Auch hier sollte man vorsichtig sein. Es ist sicherlich eine Option sinnvoll, die der Nutzerin auch dann noch den Wechsel auf eine anderssprachige Seite ermöglicht. So sind Szenarien denkbar, in denen bspw. ein englischsprachiger Browser heruntergeladen wurde, aber man dennoch deutsche Seiten auf Deutsch nutzen möchte. Oder es möchten sich Vertriebsmitarbeiterinnen einer deutschen Firma mit einem deutschen Browser eine Seite in der Sprache ihrer Kundinnen ansehen, etc. Eine Vorauswahl könnte hier dennoch für viele Kundinnen die Sache vereinfachen.

Zum SeitenanfangZum Seitenanfang

Weitere Informationen über den Client

Zusätzlich zu den Angaben, die die Userin bspw. in Formularen eingibt und die der Browser im Request übermittelt und denen, die der Browser mittels HTTP-Header mitsendet, gibt es noch ein paar weitere Angaben, die mittels des (Http)ServletRequest-Objekts abgefragt werden können. Da im Servlet- und erst recht im JSP-Kontext fast immer mit HttpServletRequests gearbeitet wird, wird im Folgenden nicht zwischen ServletRequest und HttpServletRequest unterschieden. Wer sich nicht im HTTP-Umfeld bewegt, muss ggf. in der Java-API nachschlagen, ob die Methode überhaupt im einfachen ServletRequest-Interface definiert ist.
Als erste grundlegende Informationen können wir mit getRemoteAddr() die IP-Adresse des Clients herausfinden. Mit getRemoteHost() auch den dazugehörigen Hostnamen, allerdings kann u.U. der Container aus Performance-Gründen so konfiguriert sein, dass Reverse-DNS-Abfragen nicht durchgeführt werden.
Für Uploads kann man entweder geeignete Frameworks oder Hilfsklassen verwenden (bspw. ServletFileUpload von jakarta-commons), oder aber man greift mittels getInputStream() direkt auf die binären Daten des HTTP-Requests zu. Für textuelle Daten, wie bspw. XML-Informationen liefert die Methode getReader() einen BufferedReader.
Die Methoden zum Zerlegen der URL in ihre einzelnen Bestandteile sind Gegenstand des nächsten Unterkapitels.
Sehr wichtig sind bei internationalisierten Anwendungen die Methoden getCharacterEncoding() und setCharacterEncoding(String). Während die erste lediglich das eingestellte Encoding zurückliefert, ist die zweite Methode diejenige, mit der die Anwenderin des Servlets oder der JSP auf ein im HTML-Code festgelegtes Encoding reagiert. Ist bspw. per Meta-Tag-Angaben in einer HTML-Seite (und aus JSPs wird ja letzlich HTML-Code generiert) das Encoding der Seite auf UTF-8 eingestellt, so werden die deutschen Umlaute anders übertragen, als wenn dort ISO-8859-15 verwendet wird. Bevor die Entwicklerin nun das erste mal Request-Parameter abfragt, muss sie im ersten Falle setCharacterEncoding("UTF-8") bzw. im zweiten Fall setCharacterEncoding("ISO-8859-15") aufrufen. Nur dann werden die Umlaute korrekt in das Java-interne Unicode-Format umgewandelt. Idealerweise verwendet eine Webanwendung durchgehend den gleichen Zeichensatz (bei internationalisierten Anwendungen ist UTF-8 am besten geeignet). Dann ist es am einfachsten, die entsprechende Methode in einem Servlet-Filter auf das ServletRequest-Objekt anzuwenden. Dem Thema Internationalisierung javabasierter Web-Anwendungen ist das gesamte Kapitel "Internationalisierung" gewidmet. Dort wird auch ein entsprechender Filter vorgestellt.
Als letzte Methode des HttpServletRequest-Objekt sei noch die Methode "getCookies()" erwähnt, die ein Array von javax.servlet.http.Cookie-Objekten zurück liefert. Darauf gehen wir hier allerdings nicht weiter ein. Wer Cookies nutzen möchte, findet alle notwendigen Informationen dazu im Kapitel Session-Handling, Cookies und URL-Rewriting.
Ebenfalls noch wichtig ist die Methode getRequestDispatcher(String), die zum Weiterleiten an und Inkludieren von anderen Servlets/JSPs wichtig ist. Diese wird ausführlich im Kapitel Request-Forwarding und Inklusion beschrieben und genutzt.
Alle weiteren Methoden sind eher ungebräuchlich und nur in bestimmten Anwendungsfällen von Bedeutung. Auch hier lohnt sich wie immer ein ergänzender Blick in die API.

Zum SeitenanfangZum Seitenanfang

Die Anfrage-URL und ihre Bestandteile

Das HttpServletRequest-Interface enthält zudem Methoden, wie getRequestURL(), getRequestURI(), getPathInfo() usw. Diese haben alle mit der Auflösung der vom Client genutzten URL in ihre Bestandteile zu tun, sind aber in der API eher mäßig erklärt und von ihrem Namen her auch nicht gerade selbsterklärend. Allerdings ist ihr Verständnis für manche Vorhaben ziemlich wichtig, weswegen im Folgenden zwei URLs genauer betrachtet und die einzelnen Bestandteile kurz erklärt werden.
Zunächst erstmal die zwei URLs:
screen_url_fragments.png
Wie man sofort erkennt, bestehen beide URLs aus teilweise gleichen Bestandteilen, weichen aber auch in Details voneinander ab. Wir gehen zunächst bei der obersten URL von links nach rechts vor, dann erläutern wir noch das neue Element in der zweiten URL und wieso diese zwei Bestandteile der ersten URL nicht enthält.
Der vordere Teil ist zunächst einmal das Protokoll. In unserem Fall ist das HTTP. Mitunter kann dies auch FTP sein, oder was auch immer der Browser (und natürlich auch der angesprochene Server) unterstützt. Servlets und JSPs nutzen fast immer das HTTP-Protokoll.
Daraufhin folgt der eigentliche Server. Dabei bezeichnet "jsptutorial.org" den Domain-Namen und "www" einen konkreten Host innerhalb dieser Domain (in diesem Fall auch den einzigen). Der Name wird mittels des Domain Name Systems auf eine IP-Adresse gemappt, anhand dessen der Request dann an diesen Server geroutet wird. Diese Einzelheiten sind für uns eher uninteressant.
Weitaus interessanter ist der nächste Bestandteil der URL. Dieser bezeichnet nämlich den Kontext-Pfad, der mit getContextPath() ermittelt werden kann. Der Kontext-Pfad beginnt immer mit dem ersten "/" hinter der Server-Angabe und endet vor dem nächsten "/". Im Falle des Root-Kontextes - wie in der zweiten URL - ist der Kontext-Pfad leer, die Methode gibt einen leeren String (niemals null) zurück. Kontext-Pfade entsprechen einzelnen Anwendungen innerhalb eines Containers (s. dazu auch das Kapitel Verzeichnisstruktur von Java-Webanwendungen). Im Falle des JSP-Tutorials laufen also zwei Anwendungen im Container.
Der vierte Bestandteil der ersten URL gibt den Pfad an. Dieser beginnt wiederum mit dem ersten "/" hinter dem Kontext-Pfad und geht bis zum Ende der URL oder - falls vorhanden - bis vor das Fragezeichen. Der Pfad kann beliebige Unterverzeichnisse enthalten, die der UNIX-Konvention folgend mit einem Slash und nicht mit einem Backslash getrennt werden. Wie aber erkennt der Container, dass in der URL mit "/examples" ein Kontext-Pfad und nicht ein Verzeichnis gemeint ist? Diese Unterscheidung erfolgt ausschließlich anhand der registrierten Kontexte. Existiert ein Kontext "/examples", so muss "/examples" einen Kontext kennzeichnen. Ein Verzeichnis "/examples" im Root-Kontext würde also ignoriert. Existiert hingegen kein geeigneter Kontext, so muss ein entsprechender Pfad vorliegen. Trifft beides nicht zu, gibt es den berühmten 404er-Fehler: Page Not Found.
Der letze Teil beider Pfade sind die Request-Parameter. Bei GET-Anfragen werden diese mit einem Fragezeichen vom Pfad abgetrennt an die URL angehängt. Einzelne Parameter werden wiederum durch ein "&amp;"-Zeichen getrennt. Die Parameter werden im Format key=value angehängt. Sonderzeichen werden dabei durch eine besondere Zeichen-Kombination dargestellt (%Hexwert). Bei POST-Anfragen werden die Request-Parameter nicht an die URL gehängt, sondern im Body des Requests mitgesendet (s. dazu den Anhang I: HTTP-Grundlagen). Den Parameter-String im Fall einer GET-Anfrage kann man mit getQueryString() abrufen. Meistens ist das aber unnötig, da man selten den ganzen Query-String haben will, sondern meist an den einzelnen, konkreten Parametern interessiert ist. Und die kann man, wie im obigen Unterkapitel "Formulardaten" beschrieben, besser mit getRequestParameter(String) abrufen.
Wie bei der Beschreibung des Kontext-Pfades schon erwähnt, ist im Fall der zweiten URL der Kontext-Pfad leer, die aufgerufene URL ruft also die Web-Anwendung des Roots-Kontextes auf. Daher fehlt der grüne Bestandteil. Aber es fehlt zudem auch der Pfad. Das ist wiederum erstaunlich, da der Pfad Bestandteil der URL gemäß HTTP-Spezifikation ist. Andererseits kennt die HTTP-Spezifikation ja auch keine Kontext-Pfade. Dort ist alles hinter dem Servernamen bis hin zu den Parametern eine absolute Pfadangabe. Im Fall der zweiten URL oben haben wir nun anstelle der Pfadangabe den sogenannten Servlet-Pfad (abrufbar mit getServletPath()). Dieser matcht ein Servlet, das unter diesem Pfad im Deployment-Deskriptor konfiguriert wurde. Wie genau das Matching vonstatten geht, ist relativ kompliziert und im Detail im Kapitel "Die zentrale Konfigurationsdatei "web.xml"" beschrieben. Ist kein Servlet-Pfad vorhanden, liefert die Methode getServletPath() einen leeren String zurück.
Die einzige Angabe, die es noch gibt, findet sich in keiner der obigen URLs. Dies ist die Pfad-Information (path info). Diese wird, wiederum mit einem "/" vom Servletnamen abgetrennt, hinter diesem aber noch vor den Parametern angegeben. Diese Angabe ist extrem selten.
Achtung: getPathInfo() und getQueryString() geben beiden null zurück, wenn die entsprechenden Angaben nicht vorliegen. Dies ist also anders, als beim Kontext-Pfad, oder der Methode getServletPath(), die ggf. leere Strings aber niemals null zurückgeben.

Zum SeitenanfangZum Seitenanfang

Anmerkungen:

1) Der eigentliche Client ist der Browser und nicht die Nutzerin. Aber natürlich enthält die Anfrage des Browsers auch die von der Nutzerin eingegeben Daten. Diese sind so formatiert, wie im Anhang I: HTTP-Grundlagen gezeigt. (zurück)

2) Die höchste Präferenz ist 1.0 und gilt als Default für Einträge, die keine Präferenzangabe enthalten, hier also für die Angabe "en", dem ISO-Kürzel für Englisch. (zurück)

3) Wie man im Screenshot sehen kann, nutzt der Server die Fähigkeit des Browsers, mit gzip komprimierte Dateien entpacken zu können Die gelieferten Daten sind zunächst einmal eine unverständliche Folge von Bytes, die dann, unmerkbar für die Nutzerin, vor der Anzeige ins eigentliche Format, hier also HTML, entpackt werden. Für beide Seiten (und auch zwischengeschaltete Stationen zwischen Server und Client) bedeutet dies geringeren Traffic und zudem - besonders bei einer langsamen Netzanbindung - eine deutlich bessere Antwortzeit für die Nutzerin. (zurück)

4) Leider birgt diese Methode aber auch das Risiko, dass der Client einen gefälschten HTTP-Header mitsenden kann. So können bspw. die Mozilla-basierten Browser wie Seamonkey oder Firefox, wie auch Opera, Konqueror und zahlreiche andere Browser allesamt sich als ein anderer User-Agent ausgeben. Dies erklärt sich vor allem aus der Tatsache, dass in der Vergangenheit viele Web-Designerinnen ihre Seiten für bestimmte Browser optimierten (v.a. den IE) und anhand des User-Agents häufig die Nutzerin auf eine Seite umlenkten, die dieser empfahl, doch den Browser xyz herunterzuladen. Dies sogar oft, obwohl der umgeleitete Browser die Seite problemlos darstellen konnte. Also wurde kurz vorgetäuscht, ein entsprechender Browser zu sein, und man konnte die Seite weiterhin benutzen. Insofern ist eine serverbasierte Weiche durchaus mit Vorsicht zu genießen. (zurück)


www.jsptutorial.org
© 2005, 2006, 2007