Java Blog

HttpServletRequest und HttpServletResponse und die Header

Sendet der HTTP-Client eine Anfrage an den Server, so sendet er gleichzeitig einige Informationen über sich mit. Sie nennen sich Header und bezeichnen Schlüssel-Werte-Paare, die durch einen Doppelpunkt getrennt sind. Ein Webbrowser kann zum Beispiel Folgendes formulieren:

GET /seminare/index.html HTTP/1.0
Accept-Language: de

Der Browser sendet hier den Header Accept-Language mit dem Wert de. So kann der Server unter Auswertung dieser Parameter optimal reagieren, zum Beispiel bei der Präferenz der Sprache eine lokalisierte Webseite liefern. Um an die Header zu gelangen, müssen wir das HttpServletRequest-Objekt lesen und die Header erfragen.

Header auslesen

Zum Lesen der Header in einem Servlet bieten sich zwei Lösungen an: Wenn wir einen speziellen Header erfragen wollen, dann holen wir mit getHeader() auf dem HttpServletRequest den passenden Wert zum Schlüssel. Sind wir an allen Schlüsseln interessiert, dann besorgt uns getHeaderNames() eine Enumeration. Die können wir dann durchlaufen und die Werte wiederum mit getHeader() auslesen. Falls ein Schlüssel nicht existiert, liefert die Methode null. Ähnlich wie bei getParameter() können hier auch mehrere Einträge existieren, die mit getHeaders() abgerufen werden können.

<%
java.util.Enumeration headerNames = request.getHeaderNames();
while ( headerNames.hasMoreElements() )
{
String headerNameKey = (String) headerNames.nextElement();
String headerNameValue = request.getHeader( headerNameKey );
%>
<%= headerNameKey %>: <%= headerNameValue %>
<p>
<%
}
%>

Das Servlet erzeugt für eine Anfrage etwa folgende Ausgabe:

accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
accept-language: de
accept-encoding: gzip, deflate
user-agent: Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.0)
host: localhost:8080
connection: Keep-Alive
cookie: JSESSIONID=EB9D8DFAB0D0AA1B38D292507983B6B1

Der Anfragetyp (GET, POST und so weiter) wird hier ebenso wenig angezeigt wie der Remote-Host. Dieser findet sich nicht im Header und muss mit anderen Funktionen erfragt werden.

Hilfsfunktion im Umgang mit Headern

Wieder gibt es für oft benutzte Header Abkürzungen.

Übersicht der Browser-Header

Hier eine Übersicht über die üblichen Header, von denen wir manche schon aus dem Beispiel und auch vom Server kennen:

Header, die der Server setzt

Bisher kennen wir von der Klasse HttpServletResponse die Methode setHeader() für beliebige Header.

Beispiel: Setze den Header pragma, damit vom Browser keine Daten im Cache gehalten werden:

response.setHeader( "pragma", "no-cache" );

Mit dieser Aufforderung soll der Browser die Seite jedes Mal neu laden. Das ist bei dynamischen Seiten besonders wichtig, da sie bei jedem Aufruf neu generiert werden und sich Werte ändern können, wie es zum Beispiel bei Warenkorbsystemen der Fall ist. Da wir uns als Applikationsentwickler nicht immer mit dem Namen der Header herumärgern wollen, bietet die Bibliothek einige Spezialfunktionen an.

Beispiel: Für den Header Content-Type gibt es die spezielle Methode setContentType():

response.setHeader( "Content-Type", "text/html");
response.setContentType( "text/html" );

Daneben gibt es setContentLength(), die den Header Content-Length setzt. Diese Länge muss nicht gesetzt werden und wird automatisch berechnet. Falsche Längen könnten zu Ausnahmesituationen führen. Der Gebrauch ist jedoch nützlich, wenn vorher die gesamte Webseite in einem StringBuffer sb gesammelt und in einem Rutsch übertragen wird. Dann können wir setContentLength(sb.length()) aufrufen.

Um einen Datums-Header zu setzen, existiert setDateHeader(String, long). Das Argument ist eine beliebige Zeichenkette, die mit einem Datumswert verbunden wird. Das long gibt die Millisekunden seit dem 1.1.1970 an. Die erzeugte Ausgabe schreibt einen UTC-String. Eine weitere Hilfsfunktion ist setIntHeader(), die Zahlenwerte mit Schlüsseln in den Header schreibt. Hier übernimmt die Methode die Konvertierung von String in eine Ganzzahl.

Neben diesen setXXX()-Methoden, die möglicherweise gesetzte Header überschreiben, lässt sich mit containsHeader(String) abfragen, ob Wertepaare schon gesetzt sind. Neben den setXXX()-Methoden gibt es auch entsprechende addXXX()-Methoden, die die Werte nicht überschreiben, sondern hinzufügen. Für Cookies existiert eine zusätzliche Methode namens addCookie(), die einen Cookie im Header setzt.