Grundlagen
Servlets sind Java-Klassen, welche in einer Java-Webanwendung zum Einsatz kommen. Dabei empfängt ein Servlet bestimmte Anfragen von Clients (abhängig von der URL) und kann diese beantworten. Der Inhalt kann dabei dynamisch generiert werden.
Java-Webanwendungen benötigen einen speziellen Webserver, die einen Web- bzw. Servlet-Container enthalten. Der bekannteste Webserver hierfür ist wohl Apache Tomcat. Für einige Webserver (z. B. den Microsoft-Webserver IIS) können Module verwendet werden, um auch dort Java-Webanwendungen ausführen zu können.
Bei dem Begriff Servlet handelt es sich um ein sogenanntes Kofferwort, welches sich aus den Begriffen Server und Applet (clientseitige Java-Anwendungen innerhalb einer Webseite) zusammensetzt. Servlets sind also wie Applets „kleine“ Anwendungen, die in einem Container laufen. Servlets laufen dabei in einem Container (um genauer zu sein dem Web- bzw. Servlet-Container) auf dem Webserver.
Servlets bauen aus technischer Sicht auf der CGI-Schnittstelle auf. Im Gegensatz zu anderen serverseitigen Technologien, wie z. B. PHP oder ASP.NET, werden bei Servlets HTML- und Programmcode nicht gemischt, vielmehr wird die komplette Ausgabe (also z. B. der HTML-Code) vom Programm (in diesem Fall also vom Java-Programm) erzeugt.
Schnittstellen
Eine Servlet-Klasse wird von der Klasse HttpServlet
(Package javax.servlet.http
) abgeleitet. Diese
Klasse implementiert unter anderem das Interface Servlet
(Package javax.servlet
).
Um auf eingehende Anfragen zu reagieren, müssen zu allererst die Funktionen doGet()
und doPost()
sowie ggf. auch doPut()
und doDelete()
überschrieben werden. Die oben genannten Funktionen werden
immer dann aufgerufen, wenn eine Anfrage zum Servlet mit der jeweiligen HTTP-Methode gesendet wird, d. h. sendet jemand
eine GET-Anfrage an ein Servlet, so wird dessen Funktion doGet()
aufgerufen. Möchten Sie für alle HTTP-Methoden
die gleiche Funktion verwenden, so können Sie auch die Methode service()
überschreiben. Alle diese Funktionen
geben keinen Wert zurück und besitzen als Übergabeparameter ein Objekt der Interfaces HttpServletRequest
und
HttpServletResponse
. Des Weiteren können diese Methoden Ausnahmen der Klassen ServletException
und
IOException
werfen.
Das Interface HttpServletRequest
ermöglicht den Zugriff auf einige Anfrage-Informationen, wie z. B. die
HTTP-Methode, die Anfragezeile oder die URL. Zudem können auch Formulardaten (GET/URL-Parameter sowie POST-Parameter), die
Session des Besuchers und Cookies abgerufen werden. Durch das Interface HttpServletResponse
ist es möglich, Informationen
über die HTTP-Antwort abzurufen, aber auch zu ändern. Des Weiteren ist es auch möglich, Weiterleitungen oder das Setzen von
Cookies mit Hilfe dieser Interfaces zu realisieren. Beide Interfaces werden wir jedoch im
nächsten Thema noch genauer besprechen.
Wie viele andere Klassen besitzt auch die HttpServlet
-Klasse die Funktionen init()
und destroy()
.
Diese können überschrieben werden, um Ressourcen für das Servlet zu reservieren und am Ende wieder freizugeben. Bei dem Aufruf
eines Servlets wird vom Servlet-Container als erstes eine Instanz des Objekts erstellt und dann die init()
-Methode
aufgerufen. Anschließend wird eine der doX()
-Methoden bzw. die service()
-Methode aufgerufen. Am Ende
wird die destroy()
-Funktion aufgerufen und letztendlich die Objektinstanz wieder gelöscht.
Konfiguration
Servlets bzw. Java-Webanwendungen müssen grundsätzlich konfiguriert werden. Dafür gibt es die Datei web.xml
, welche
auch als Deployment Descriptor bezeichnet wird. Diese Datei (im Falle einer Web-Anwendung) besitzt das Wurzelelement
web-app
. In dieser Datei wird üblicherweise das Attribut version
sowie einige XML-spezifische Attribute
(xmlns
u. a.) angegeben. Dies sieht dann wie folgt aus:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> </web-app>
Jedes Servlet, welches nachher von außen zugänglich sein soll, muss in der web.xml
-Datei erstmal registriert
werden. Dazu wird das Element servlet
angegeben. In diesem befinden sich wiederum die Elemente servlet-name
und servlet-class
. Der Wert innerhalb von servlet-name
legt den internen (für die XML-Datei geltenden)
Namen des Servlets fest. Im Element servlet-class
wird die Klasse des Servlets inkl. dem Package angegeben.
<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>de.hwh.bsp.hallowelt.HelloServlet</servlet-class> </servlet>
Um nun eine gewisse URL mit einem Servlet zu verbinden, benötigen wir das Element servlet-mapping
, welchem die
Elemente servlet-name
(dort wird der interne Name des Servlets „von oben“ angegeben) und url-pattern
untergeordnet werden. Als Wert des Elements url-pattern
kann ein URL-Muster angegeben werden. Dabei
ist es auch möglich, mit dem Wildcard-Zeichen *
zu arbeiten. Mit dem Muster /Download/*.zip
könnte
man bspw. alle Anfragen auf eine ZIP-Datei aus dem Ordner /Download/
auf ein gewisses Servlet lenken.
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
Neben den genannten Elementen gibt es noch viele weitere, die dazu genutzt werden können, eine Web-Anwendung zu konfigurieren. Hierzu zählt z. B. das automatische Timeout von Sessions.
Erstes Servlet
Nachdem wir uns nun mit der grundlegenden Theorie in Bezug auf Servlets beschäftigt haben, wollen wir nun unser erstes Servlet erstellen. Alle in diesem Tutorial enthaltenen Beispiele wurden mit der Entwicklungsumgebung NetBeans erstellt und mit dem JDK 8 (mit der Java EE Version 6) kompiliert.
Um eine Java-Webanwendung zu erstellen, müssen wir als erstes ein neues Projekt anlegen. Bei der Projekt-Erstellung müssen wir unter „Categories“ „Java Web“ auswählen. In der Auswahlbox „Project“ wählen wir „Web Application“.
Als nächstes werden Name und Speicherort des Projekts festgelegt. Anschließend werden die Servereinstellungen festgelegt. Dort muss der Server, die Java-EE-Version und der Pfad ausgewählt bzw. eingegeben werden. Wurde noch kein Server angelegt, was bei der ersten Erstellung des ersten Projekts der Fall ist, so müssen Sie diesen zuerst erstellen. Hier können Sie, sofern Sie mit XAMPP entwickeln, NetBeans mit dem in XAMPP enthaltenen Apache Tomcat Webserver verbinden. Dazu wählen Sie als erstes „Apache Tomcat or TomEE“ aus und geben anschließend den Pfad des Server-Verzeichnisses sowie einen Benutzernamen und ein Passwort ein.
Im letzten Schritt können noch Frameworks ausgewählt werden, welche eingebunden werden sollen. Für unsere Servlet-Beispiele benötigen wir jedoch keine Frameworks.
Von NetBeans wird bei den oben genannten Schritten eine JSP-Seite (Datei index.jsp
) erzeugt. Diese können Sie löschen,
da wir diese zurzeit nicht benötigen. Unter dem Projektordner „Source Packages“ können Sie bei Bedarf ein Package und anschließend
ein Servlet anlegen. Nach dem Festlegen des Namens und des Speicherorts können Sie das Servlet dem Deployment Descriptor
hinzufügen. Auch hier ist uns der Assistent von NetBeans eine große Hilfe. Dadurch werden die Einstellungen automatisch in die
Datei web.xml
hinzugefügt. Beim Erstellen des ersten Servlets wird die Datei web.xml
angelegt.
Das Erstellen eines neuen Servlets mit Hilfe des Assistenten erzeugt eine Java-Quellcodedatei, in welcher die Klasse des Servlets
definiert ist. In der Klasse werden die Methoden doGet()
, doPost()
und getServletInfo()
überschrieben. doGet()
und doPost()
rufen die lokale Funktion processRequest()
auf.
Das Projekt kann direkt von der IDE heraus in den Webserver geladen und das Ergebnis betrachtet werden. Auch das Debuggen von Java Web-Anwendungen ist möglich.
Im folgenden Beispiel wurde der Quellcode etwas gekürzt und der Inhalt der Funktion processRequest()
verändert. Bei
diesem und den folgenden Beispielen haben Sie die Möglichkeit, sich das Ergebnis anzuschauen, indem Sie auf die Lupe klicken.
Ein Klick auf den Pfeil nach unten startet den Download des NetBeans-Projekts.
Servlet (HelloServlet.java):
package de.hwh.bsp.hallowelt; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Ausgabe als Text-Datei response.setContentType("text/plain;charset=UTF-8"); // Ausgabe durchführen PrintWriter out = response.getWriter(); out.println("Hallo Welt!"); out.println(); out.println("Aktuelles Datum und Uhrzeit: " + (new Date()).toString()); out.close(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
Konfiguration (web.xml):
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>de.hwh.bsp.hallowelt.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app>