Servlet
Willemers Informatik-Ecke
Ein Servlet ist ein Java-Programm, das die Klasse HttpServlet erweitert und in einem Applikationsserver läuft. Der Applikationsserver stellt die Netzwerkumgebung zur Verfügung und ruft das Servlet auf, wenn dessen Adresse von außen angetragen wird.

Ein Servlet ist in der Lage, ein HTML-Formular auszuwerten.

Für die Entwicklung wird eine spezielle Laufzeit- und Entwicklungsumgebung eingerichtet. Danach kann in Eclipse auf folgendem Weg ein Projekt erzeugt werden.

Ein HTML-Formular

Durch einen Rechtsklick auf das Projekt kann eine HTML-Datei generiert werden. Dazu wird im Menü New...|HTML File ausgewählt. In diesem HTML-Dokument wird ein einfaches Formular eingesetzt, das drei Eingabefelder und einen Submit-Button aufnimmt.
<html>
<head>
</head>
<body>
<form action=Insert method=get>
<table>
<tr><td>ID (Kürzel)</td><td> <input type=text name=id value="" size=30></td></tr>
<tr><td>Klarname</td><td> <input type=text name=klarname value="" size=30></td></tr>
<tr><td>E-Mail</td><td> <input type=text name=email value="" size=30></td></tr>
<tr><td><input type=submit value="Einfügen"></td><td> </td></tr>
</table>
</form>
</body>
</html>
Bei Anklicken des Submit-Buttons wird die Aktion Insert aufgerufen. Dahinter steckt nun ein Servlet.

Das Servlet

Das Servlet läuft im Application Server (beispielsweise Tomcat oder Glassfish), das ihm als Runtimesystem dient. Servlet ist ein Interface, muss also implementiert werden. Das betrifft folgende Methoden:

Die von Servlet abgeleitete Klasse HttpServlet hat zusätzlich die HTTP-typischen Methoden doGet, doPost, doDelete, doPut und andere zu bieten. Dabei interessiert sich das Servlet meist für doGet und doPost.

Aus der Sicht von Eclipse werden Servlets in einem Dynamic Web Project erstellt. Zum Anlegen eines Servlets innerhalb eines solchen Projekts, klicken Sie das Projekt an und erzeugen über den Menüpfad New...|Servlet einen Dialog. Der Name des Servlets soll Insert lauten.

Eclipse erzeugt einen Rahmen für ein Servlet, den wir hier erweitern. Insbesondere wird die Methode doGet() überschrieben, da diese aufgerufen wird, weil das Formular oben die Methode get verwendet.

Die Methode doGet hat zwei Parameter:

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/Insert")
public class Insert extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Insert() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.getWriter().println("<table>");
        // Hole alle Parameterbezeichner
        Enumeration<String> controls = request.getParameterNames();
        while (controls.hasMoreElements()) {
            String controlName = controls.nextElement();
            // Zeige den Parameterbezeichner
            response.getWriter().println("<tr><td>" + controlName);
            // Zeige den eingegeben Wert
            response.getWriter().println("</td><td>" + request.getParameter(controlName) + "</td></tr>");
        }
        response.getWriter().println("</table>");
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
Die Methode doGet() liest zunächst die Namen aller Kontrollelemente des aufrufenden Formulars aus, um daraus eine Tabelle der Kontrollelemente und ihrer Inhalte zu erstellen.

Der Parameter request

Der Parameter request von der Klasse HttpServletRequest liefert verschiedene Informationen.

Die Parameter eines FORM

Die Attribute und die Weiterleitung

Die Daten der Anfrage stehen in den Attributen des Parameters request der Klasse HttpServletRequest zur Verfügung. Damit können sie von anderen Servlets oder Java Server Pages ausgelesen werden.

Es können auch eigene Daten zu den Request-Daten hinzugefügt werden.

String strName;
// ...
request.setAttribute("name", strName);
Anschließend können die Daten server-intern weitergeleitet werden. Davon bemerkt der Client nichts. Für die Weiterleitung an eine JSP-Seite wird der RequestDispatcher benötigt, der über getRequestDispatcher ermittelt wird. Über den Aufruf der Methode forward wird das server-interne Ziel angegeben - hier eine Java-Server-Page.
RequestDispatcher dispatch = request.getRequestDispatcher("anzeige.jsp");
dispatch.forward(request, response);
Damit wird die Anfrage des Clients intern an die Seite anzeige.jsp umgeleitet. Diese kann nun das Attribut mit der folgenden Anweisung wieder auslesen:
String str = request.getAttribute("name");

HttpSession

HTTP-Kommunikation kennt eigentlich keine Sessions, die aber gebraucht werden, um beispielsweise einen Einkauf über mehrere Seiten zu verfolgen.

Allerdings stellt das Servlet eine einfache Lösung zur Verfügung. Aus dem Request-Parameter kann mit der Methode getSession die aktuelle Session ermittelt werden. Gibt es noch keine, wird eine angelegt.

HttpSession session = request.getSession();

Sessions können mit Cookies realisiert werden, durch Erweitern der URL um eine Session-ID (insbesondere bei GET) oder durch verborgene Eingabeelemente. Standardmäßig werden Cookies verwendet.

Mit den folgenden Methoden kann der Session Werte zugeordnet werden:

Die Methoden sind überladen. Es ist möglich, Strings oder primitive Typen zu verwenden, aber auch alle Objekte, die Object erweitern (also alle). Bei getAttribute muss dabei natürlich gecastet werden, da Object zurückgegeben wird. Diese Objekte sind in der Regel JavaBeans.

Weitere Methoden des Request-Parameters

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

Cookie[] cookies = request.getCookies();

InputStream in = request.getInputStream();

Der Parameter response

Der Parameter response von der Klasse HttpServletResponse erlaubt den Zugriff auf die HTTP-Antwort des Servers.

Ausgabe an den Client

Über den Aufruf von getWriter des Objekts response erhalten Sie ein Objekt der Klasse PrintWriter. Darüber können Sie mit print und println schreiben, wie Sie es von System.out gewohnt sind. Auf diese Weise kann HTML-Source an den Browser geschickt werden, der den Unterschied zu einer normalen Website nicht merken wird.

PrintWriter writer = response.getWriter();
writer.print("\n...
...
Wenn der Umfang der HTML-Ausgabe größer wird, ist es sinnvoller, auf eine Java Server Page-Seite umzuleiten.

Sollen binäre Daten an den Client versandt werden, liefert die Methode getOutputStream einen ServletOutputStream, über dessen Methode write Binärdaten an den Client gesant werden können.

ServletOutputStream os = response.getOutputStream();
os.write(bytearray);

Umleiten auf eine andere Seite

response.sendRedirect(“ausgabe.jsp“)
Der Browser (also der Client) wird auf die Seite ausgabe.jsp umgelenkt. JSP-Dateien sind eigentlich verkappte Servlets. Sie sehen auf den ersten Blick aus wie HTML-Seiten, haben aber Java-Code eingebettet.

Natürlich lässt sich auch auf HTML-Seiten umleiten. Der Parameter von sendRedirect akzeptiert alle URLs, auch die von anderen Servern.

Header- und Statusveränderungen

Die response-Variable stellt die Methoden setHeader und addHeader zur Verfügung. Damit lassen sich Einträge im Header festlegen oder hinzufügen.

Das Servlet liefert als Status normalerweise OK mit der 200 zurück. Dieser Status kann durch die Response-Methode setStatus geändert werden:

response.setStatus(HttpServletResponse.SC_OK); // 200
response.setStatus(HttpServletResponse.SC_SEE_OTHER); // 303
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); // 307
Auf 303 oder 307 folgt normalerweise ein Headereintrag für die neue Location:
response.setHeader("Location", "alternativ.html");
Sollte es bitter kommen, ist der Status ein Fehler, wie etwa 404. Dies wird nicht per setStatus, sondern per setError übermittelt.
response.setError(HttpServletResponse.SC_NOT_FOUND); // 404

ServletConfig

Die Methode init erhält als Parameter das Objekt der Klasse ServletConfig, das vom Application Server für das Servlet angefertigt wurde. Es enthält Informationen aus der Konfigurationsdatei web.xml, die Eclipse freundlicherweise automatisch erstellt hat.

Lebenszyklus

Ein Servlet arbeitet als Singleton und wird bei seinem ersten Aufruf gestartet. Dabei wird die Methode init aufgerufen.

Jede Clientaufforderung führt zu einem Aufruf von service, bei einem HttpServlet zum Aufruf von doGet, doPost, doDelete und anderen, je nach HTTP-Kommando. Jede Anfrage läuft in einem separaten Thread für jeden Request.

Die Umgebung seines Aufrufs findet das Servlet in den Parametern (request und response). Globale Variablen stehen allen Aufrufern des Servlets zur Verfügung.

Um Abläufe mit mehreren Aufrufen zu verbinden, können Sessions angelegt werden, in dem die Daten eines Clients abgelegt werden können.

Auf ein Zugriff auf Cookies ist möglich.

Beim Herunterfahren des Servers wird das Servlet beendet. Dabei wird dessen Methode destroy noch einmal aufgerufen.

Links