Die großen Umbenennungen: Java EE -> Jakarta EE

Quelle: https://blogs.eclipse.org/post/wayne-beaton/renaming-java-ee-specifications-jakarta-ee

  • Replace “Java” with “Jakarta” (e.g. “Java Message Service” becomes “Jakarta Message Service”);
  • Add a space in cases where names are mashed together (e.g. “JavaMail” becomes “Jakarta Mail”);
  • Add “Jakarta” when it is missing (e.g. “Expression Language” becomes “Jakarta Expression Language”); and
  • Rework names to consistently start with “Jakarta” (“Enterprise JavaBeans” becomes “Jakarta Enterprise Beans”).

Das heißt:

  • Jakarta APIs for XML Messaging
  • Jakarta Architecture for XML Binding
  • Jakarta API for XML-based Web Services
  • Jakarta Common Annotations
  • Jakarta Enterprise Beans
  • Jakarta Persistence API
  • Jakarta Contexts and Dependency Injection
  • Jakarta EE Platform
  • Jakarta API for JSON Binding
  • Jakarta Servlet
  • Jakarta API for RESTful Web Services
  • Jakarta Server Faces
  • Jakarta API for JSON Processing
  • Jakarta EE Security API
  • Jakarta Bean Validation
  • Jakarta Mail
  • Jakarta Beans Activation Framework
  • Jakarta Debugging Support for Other Languages
  • Jakarta Server Pages Standard Tag Library
  • Jakarta EE Platform Management
  • Jakarta EE Platform Application Deployment
  • Jakarta API for XML Registries
  • Jakarta API for XML-based RPC
  • Jakarta Enterprise Web Services
  • Jakarta Authorization Contract for Containers
  • Jakarta Web Services Metadata
  • Jakarta Authentication Service Provider Interface for Containers
  • Jakarta Concurrency Utlities
  • Jakarta Server Pages
  • Jakarta Connector Architecture
  • Jakarta Dependency Injection
  • Jakarta Expression Language
  • Jakarta Message Service
  • Jakarta Batch
  • Jakarta API for WebSocket
  • Jakarta Transaction API

Kommerzielle Unterstützung für GlassFish läuft aus

Quelle:

Bemerkungen dazu unter

Oracle handelt in meinen Augen (wieder einmal) aus rein ökonomischen Interessen; es geht nicht gut, zwei Produkte in einem Marktsegment zu positionieren, die Geschichte hatten wir schon mit Oracle Database und MySQL.

Möglicherweise wird GlassFish (und die assoziierten Java EE-Teile, wie Web-Services, OR-Mapper) eine Spielwiese für Technologien, die dann in WebLogic übertragen werden, wenn sie funktionieren, und dort dann exklusiv verbessert und optimiert.

Ob ich Kunden nun zu GlassFish raten würde? Eher nicht. Bis gestern war ich absoluter GF-Fan und habe den Server immer empfohlen, auch gegen den starken JBoss, doch wenn kein kommerzieller Support vorhanden ist, werden große Unternehmen ihn schlicht nicht einsetzen wollen.

Bye Bye GF

Session-Verwaltung in Servlets mit HttpSession

Die Servlet-API bietet die Klasse HttpSession an, eine Bibliothek auf hohem Niveau für die Verwaltung einer Sitzung. Sie basiert entweder auf Cookies oder URL-Rewriting, doch wird das von der API transparent gehalten. Als Programmierer bekommen wir so gut wie gar nichts davon mit. Falls der Client keine Kekse mag, wandeln wir alle Informationen in URLs um, die wir dann anbieten. Ein Sitzungsobjekt verwaltet die gesicherten Daten auch selbstständig in einer Datenstruktur. Hier fällt für uns keine Arbeit an.

Das mit einer Sitzung verbundene Objekt HttpSession

Jede Sitzung ist mit einem Sitzungsobjekt verbunden, das die Klasse HttpSession abbildet. Bei JSPs repräsentiert das implizite Objekt session die aktuelle Sitzung.

Werte mit einer Sitzung assoziieren und auslesen

Um Informationen mit der Sitzung zu verbinden, verwenden wir die Methode setAttribute(), die einen Schlüssel und einen Wert verbindet. Daten werden mit getAttribute() wieder aus der Datenstruktur gelockt, so wie es das folgende Beispiel zeigt:

List l = (List) session.getAttribute( "artikel" );

Hier verbinden wir mit einem Schlüssel eine Liste von Waren. Im Hintergrund werden die Informationen auf der Serverseite gesichert. Die Informationen selbst werden nicht in Cookies oder in der URL abgelegt, daher spielt die Größe der Daten auch keine Rolle. Ein HttpSession-Objekt verwaltet einen Assoziativspeicher, der die Wertepaare speichert. Es ist günstig, die Elemente serialisierbar zu gestalten, um die Daten dauerhaft zu speichern.

Werfen wir abschließend einen Blick auf das Programmstück, das eine neue Ware hinzufügt:

List l = (List) session.getAttribute( "artikel" );
if ( l == null )
{
  l = new ArrayList();
  session.setAttribute( "artikel", l );
}
l.add( w );

interface javax.servlet.http.HttpSession

  • Object getAttribute( String name )

    Liefert das mit name verbundene Objekt; null, wenn es keine Assoziation gab.
  • Enumeration getAttributeNames()

    Liefert eine Aufzählung aller mit der Sitzung verbundenen Objekte.
  • void setAttribute( String name, Object value )

    Bindet name mit dem Objekt value an die Sitzung. Existierte das Objekt, wird es ersetzt. Angemeldete HttpSessionBindingListener werden über die Methode value Bound() beziehungsweise valueUnbound() informiert.
  • void removeAttribute( String name )

    Entfernt das Attribut von der Sitzung. Ungültige Namen werden ignoriert. HttpSession BindingListener werden durch Aufruf von valueUnbound() informiert.

Alle Methoden liefern eine IllegalStateException, wenn die Sitzung ungültig ist. Die Methoden putValue() und setValue() sind veraltet und wurden durch setAttribute() und getAttribute() ersetzt.

URL-Rewriting

Das Session-Management sollte im Prinzip unabhängig von der technischen Umsetzung sein. Doch leider greift das Sitzungsmanagement beim URL-Rewriting schon sehr stark ein: Bei jedem Verweis auf eine neue Seite muss die URL entsprechend angepasst werden, weil die Sitzungs-ID mitgeschickt werden muss. Cookies verwalten die Sitzungs-ID völlig anders. Das bedeutet: Werden Cookies eingesetzt, ändert sich die URL nicht und jeder kann problemlos auf eine neue Seite verweisen. Nur beim URL-Rewriting muss an die URL eine Sitzungskennung angehängt werden.

Beispiel Eine URL für einen Cookie besitzt keine Sitzungskennung.

  • http://localhost/servlet/URLRewritingSession

Mit URL-Rewriting sieht das dann etwa so aus:

  • http://localhost/servlet/URLRewritingSession;jsessionid=abcde234

Wenn wir innerhalb eines Servlets auf eine andere generierte Seite verweisen wollen, haben wir eine URL vor uns, zu der wir verzweigen möchten. Die Servlet-API kümmert sich darum, an eine Benutzer-URL die Sitzungs-ID automatisch anzuhängen. Dazu dienen die HttpServletResponse-Methoden encodeURL() und encodeRedirectURL().

Beispiel: Aufgrund einer Formularbestätigung soll auf eine JSP-Seite mit dem Namen validate.jsp verwiesen werden:

<form action='<%= response.encodeURL("/validate.jsp") %>'>

Werden der Verweis und die Kodierung aus Versehen vergessen, ist dies das Ende der Sitzung. Ob eine Sitzung mit einem Cookie behandelt wird, lässt sich mit isRequestedSessionIdFromCookie() testen. Dann kann aufgrund einer Fallunterscheidung encodeURL() verwendet werden oder nicht. Allgemein ist es aber nicht schlecht, grundsätzlich alle Verweise innerhalb einer Webapplikation mit encodeURL() zu sichern. Im Fall von Cookies wird zwar keine Kennung angehängt, eine spätere Umstellung gestaltet sich aber einfacher, falls der Nutzer die Cookies einmal ausschaltet.

Zusätzliche Informationen

Ein Sitzungsobjekt verwaltet neben den assoziierten Daten noch weitere Informationen. Jede Sitzung bekommt eine eindeutige ID, die sich mit getId() erfragen lässt. Ist die Sitzung neu und hat der Client noch nie eine Verbindung gehabt, gibt isNew() den Wert true zurück. Existiert dann die Sitzung, gibt getCreationTime() ein long zurück – kodiert sind wie üblich die vergangenen Millisekunden seit dem 1.1.1970 –, in dem sich das Erstellungsdatum erfragen lässt. Dagegen erfragt getLastAccessedTime() die Zeit, die seit dem letzten Zugriff durch den Client vergangen ist. Falls der Server die Informationen dauerhaft speichert und der Cookie nicht abläuft, erlaubt dies Meldungen der Art: »Schön, Sie nach zwei Wochen zum fünften Mal bei unserer Partnervermittlung wiederzusehen. Hat’s wieder nicht geklappt?«

Das Ende der Sitzung

Eine Sitzung ist nicht automatisch unendlich lange gültig. Bei Cookies lässt sich der Gültigkeitszeitraum einstellen. Auch Sitzungsobjekte lassen sich in der Zeit anpassen. Die Methode setMaxInactiveInterval() setzt den Wert, wie lange eine Sitzung gültig ist. Ist der Wert negativ, zeigt er an, dass die Sitzung nicht automatisch beendet wird. Die entsprechende Methode getMaxInactiveInterval() liefert die Zeit in Sekunden, in der eine Sitzung gültig ist.

interface javax.servlet.http.HttpSession

  • long getCreationTime()

    Gibt in Millisekunden ab dem 1.1.1970 an, wann die Sitzung eröffnet wurde.
  • String getId()

    Liefert eine eindeutige Kennung, die die Sitzung identifiziert.
  • long getLastAccessedTime()

    Gibt in Millisekunden ab dem 1.1.1970 zurück, wann der Client zum letzten Mal auf den Server zugegriffen hat.
  • int getMaxInactiveInterval()
  • void setMaxInactiveInterval( int interval )

    Liefert und setzt die Zeit, für die der Servlet-Container die Sitzung aufrechterhalten soll, bis sie ungültig wird.
  • boolean isNew()

    Der Rückgabewert ist true, wenn die Sitzung neu ist.

Beispiel Zum Schluss wollen wir ein Programm formulieren, das alle diese Informationen auf einmal ausgibt.

<%@ page language="java" import="java.util.*" %>
<%
int cnt = 0;
if ( session.isNew() )
{
out.println( "Willkommen Neuling!\n" );
}
else
{
out.println( "Hallo, alter Freund!\n" );
String o = (String) session.getAttribute( "cnt" );
if ( o != null )
cnt = Integer.parseInt( o );
cnt++;
}
session.setAttribute( "cnt", ""+cnt );
%>
<p>
Session-ID: <%= session.getId() %> <p>
Erzeugt am: <%= new Date(session.getCreationTime()) %> <p>
Letzter Zugriff: <%= new Date(session.getLastAccessedTime()) %> <p>
Ungültig in Minuten: <%= session.getMaxInactiveInterval()/60 %> <p>
Anzahl Zugriffe: <%= cnt %>

Das Programm liefert beispielsweise folgende Ausgabe:

Hallo, alter Freund!
ID: 91410050092487D9B5D0D2A7A3D0F072
Erzeugt am: Fri Jan 18 20:16:49 CET 2002
Letzter Zugriff: Fri Jan 18 20:23:33 CET 2002
Ungültig in Minuten: 30
Anzahl Zugriffe: 4

Die ID sieht bei jedem Server anders aus. Der Webserver von Sun erzeugt beispielsweise ganz andere Kennungen.

Automatisches Neuladen von Servlet-Seiten

Über das implizite Objekt response lassen sich Antworten von der JSP-Seite an den Client formulieren. Das Setzen von Content-Type ist für nahezu alle Servlets unabdingbar. Daneben gibt es noch weitere, die beispielsweise für Cookies interessant sind. Ein spezieller Header kann auch das Caching beeinflussen (mit dem Datum der letzten Modifizierung) oder die Seite nach einer bestimmten Zeit neu laden. Letzteres wollen wir verwenden, um eine einfache Ausgabe zu erzeugen, die jede Sekunde neu geladen wird. (Die Seite darf jedoch nicht im Cache liegen. Um das Caching explizit auszuschalten, sollte Pragma: no-cache gesetzt werden. Bei einer lokalen Installation spielt dies jedoch keine Rolle.

<%! private String result = "*"; %>
<% response.setHeader( "Refresh", "1" ); %>
<%= result += "*" %>

Dieses Servlet erzeugt eine Reihe von Sternchen, wobei es sich die Zeichenkette jede Sekunde neu vom Server holt. Das dargestellte Programm zeigt in einfacher Weise auf, was sich noch wesentlich komplexer mit Threads anstellen lässt. Im Hintergrund hätten wir einen Thread starten können, der ständig eine neue Berechnungen durchführt, die wir dann in der println()-Zeile hätten ausgeben können.

In Servlets Seiten über HTTP-Redirect umlenken

Ist eine Seite nicht mehr korrekt, kann sie umgelenkt werden. Hierfür wird ein spezieller Header gesetzt.

sendRedirect()

Dazu dient die Methode sendRedirect(String), die auf eine neue Seite verweist. Als Argument kann eine relative oder absolute URL aufgeführt werden, die auf eine temporäre neue Seite weist. Wir könnten auch mit setHeader() arbeiten, müssten dann aber von Hand den Statuscode ändern, der für Umleitungen auf 302 gesetzt sein muss. Die Arbeit können wir uns sparen. Nach dem Setzen der Umleitung sollte nicht mehr in die Ausgabe geschrieben werden.

Wozu kann nun diese Umleitung eingesetzt werden? Zum Beispiel, um über Formular-Parameter zu externen Seiten weiterzuleiten:

response.sendRedirect( url );

Nach der Umleitung steht der Ort der neuen Seite in der URL-Zeile des Browsers. Das folgende Programm verweist nun einfach auf ein anderes Servlet. Die Pfadangabe kann absolut oder relativ sein.

String url = "http://www.tutego.de/";
response.sendRedirect( url );

Was passiert beim Umlenken?

Technisch gesehen ist eine Umlenkseite eine ganz normale Webseite. Das wirkliche Umlenken ist eine Fähigkeit des Browsers und nicht des Servers. Dies ist wichtig anzumerken, weil eigene Programme, die URL-Verweise aufbauen, hier oft nicht korrekt vorgehen.

Das Servlet setzt beim sendRedirect() den Content-Type auf "text/html". Wichtig sind zwei weitere Informationen: die eine in der Statuszeile und die andere im Header. In der Statuszeile wird die Nummer 302 gesendet, die das Umlenken bezeichnet. Die Information darüber, wohin verwiesen wird, steht in einem weiteren Header namens »Location«. Somit können wir unser Redirect prinzipiell auch selbst ausformulieren, indem wir Folgendes schreiben:

response.setStatus( 302 );
response.setContentType( "text/html" );
response.setHeader( "Location", url );

Der String url ist dann eine Referenz auf die neue Seite. Der Verweis auf die externe Seite muss dann natürlich absolut sein. Dies regelt jedoch sendRedirect() automatisch.

Parametersammlungen im Servlet mit getParameterValues() auslesen

Da ein Parameter auch mehr als einen Wert haben kann, hilft getParameter() nicht weiter, da dieser nur jeweils einen Wert liefert. Hier führt die Methode getParameterValues() zum Ziel, die ein Feld von Strings zurückgibt. (Damit ist kein zusammengesetzter String etwa für Suchmaschinen gemeint.) Sind wir an einer vollständigen Aufzählung der Schlüssel interessiert, liefert getParameterNames() ein Objekt vom Typ Enumeration zurück, mit dem wir durch das Feld wandern und die Werte mit getParameter() erfragen können.

<%
java.util.Enumeration paramNames = request.getParameterNames();
while ( paramNames.hasMoreElements() )
{
 String param = (String) paramNames.nextElement();
 out.print( "<p>" + param + " = " );
 String[] paramValues = request.getParameterValues( param );
 if ( paramValues.length == 1 )
 {
  String paramValue = paramValues[0];
  if ( paramValue.length() == 0 )
   out.println( "unbestimmt" );
  else
   out.println( paramValue );
 }
 else
 {
 for ( int i = 0; i < paramValues.length; i++ )
  out.print( paramValues[i] + " " ) ;
  out.println( "<p>" );
 }
}
%>

Wenn wir das Programm mit der Zeile

http://localhost:8080/jt/parameterNames.jsp?a=1&b=2&c=&a=2

im Browser starten, erzeugt das Servlet folgende Ausgabe:

b = 2
a = 1 2
c = unbestimmt

Wir sehen, dass alle Parameter hier aufgeführt sind, doch in unbestimmter Reihenfolge. Dies ist aber egal. Das Programm erkennt, ob ein Wert gesetzt ist oder nicht beziehungsweise ob einem Schlüssel ein Wert zweimal zugewiesen wurde.

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.

  • getMethod() liefert eine Zeichenkette wie GET oder POST.
  • Die Methode getRequestURI() liefert die URI der Anfrageseite.
  • getProtocol() liefert das Protokoll von der Statuszeile, also heutzutage entweder HTTP/1.0 oder HTTP/1.1.
  • getCookies() liefert den Inhalt des Cookie-Headers (dazu später mehr).
  • getAuthType() und getRemoteUser() zerteilen die Information im Authorization-Feld in Komponenten.
  • getDateHeader() und getIntHeader() sind wieder Hilfsmethoden.

Übersicht der Browser-Header

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

  • Accept. Der vom Browser bevorzugte MIME-Typ.
  • Accept-Charset. Der vom Browser bevorzugte Zeichensatz.
  • Accept-Encoding. Die Kodierung, die der Browser verarbeiten kann, wie etwa gzip oder compress. Unser Servlet-Programm sollte vor dem Komprimieren testen, ob der Browser überhaupt komprimierte Dateien verarbeiten kann.
  • Accept-Language. Die Sprache, die der Browser bevorzugt anzeigt. Mehr als ein Eintrag, wenn der Browser mehr als eine Sprache spricht.
  • Authorization. Information über Autorisierung, die normalerweise eine Antwort auf die WWW-Authenticate-Anfrage des Servers ist.
  • Connection. Informiert, ob persistente Verbindungen genutzt werden. Persistente Übertragungen übermitteln in einer TCP/IP-Verbindung mehrere Dateien, etwa eine HTML-Datei und mehrere Grafiken. Wenn der Wert von Connection »Keep-Alive« heißt, dann lassen sich mit einer Netzwerkverbindung mehrere Seitenteile übermitteln. Wenn die Request-Zeile die http-Version 1.1 anzeigt, sind Keep-Alive-Verbindungen Standard. Unsere Aufgabe bei diesen Verbindungen ist es, den Header ContentLength in die Antwort zu setzen. Server-abhängig wird hier teilweise schon automatisch in einen Puffer geschrieben und die Größe gesetzt. Dies muss aber nicht so sein, daher bietet es sich an, die Informationen in einen ByteArrayOutputStream zu schreiben, um später die Länge und den Inhalt abzufragen.
  • Content-Length. Die Länge des Bytestroms. Hier zählt der Browser die Bytes und informiert den Server, wie viele Daten noch kommen.
  • Cookie. Cookie-Information, die der Browser automatisch mitschickt.
  • From. Ein optionaler Header, der oft von Webrobotern gesetzt wird. Bei Browsern nicht üblich.
  • Host. Rechnername und Host, wie in der Original-URL angegeben.
  • If-Modified-Since. Liefert ein neues Server-Dokument, wenn die im Header angegebene Zeit auf ein neueres Dokument verweist. Ist das Browser-Dokument aktueller, gibt der Server den Antwortcode 304 mit der Nachricht »Not Modified« zurück.
  • Pragma. Gibt Informationen über das automatische Neuladen der Seiten. Der Wert no-cache zeigt an, dass der Server immer eine neue Seite liefern soll, auch wenn der Proxy eine Kopie hält.
  • Referer. Die URL mit dem Verweis, der auf die aktuelle Seite gezeigt hat.
  • User-Agent. Der Browsertyp. Praktisch, wenn unser Servlet JavaScript-Code einbettet, der vom Browser abhängig ist.
  • UA-Pixels, UA-Color, UA-OS, UA-CPU. Von Microsoft eingeführte proprietäre Header für den Internet Explorer, die Bildschirmgröße, Farbtiefe, Betriebssystem und CPU-Typ anzeigen.

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.