Servlet-Syntax

(Auszug aus "Java und XSLT" von Eric M. Burke)

Unter Java-basierte Webtechnologien wurde die Architektur von Servlets behandelt und mit einigen anderen Ansätzen verglichen. Die Architektur eines Systems ist vergleichbar mit einem Blick aus der Vogelperspektive, bei dem Implementierungsdetails ignoriert werden. Wir werden uns jetzt mit der Problematik der Syntax beschäftigen, um in den letzten Kapiteln mit den wirklich interessanten Beispielen fortzufahren. Eine umfassende Diskussion von Servlets finden Sie in Jason Hunters Java Servlet-Programmierung (O’Reilly). Da sich in der Welt der Servlets seit der ersten Ausgabe dieses Buches sehr viel geändert hat, sollten Sie auf alle Fälle die zweite Ausgabe verwenden.

Beispiel: Testbild-Servlet

Unser erstes Beispiel wird ein einfaches Testbild erzeugen. Das Servlet empfängt einen Request von einem Browser und gibt eine HTML-Seite aus. Die folgende Abbildung zeigt das Klassendiagramm von SplashScreenServlet, welches von HttpServlet abgeleitet ist.

Klassendiagramm von SplashScreenServlet

Abbildung: Klassendiagramm von SplashScreenServlet

Servlets werden fast immer von HttpServlet abgeleitet. In unserem Beispiel überschreiben wir die Methode doGet( ), die jedesmal aufgerufen wird, wenn der Browser eine HTTP-GET-Anfrage an den Server absetzt. GET-Anfragen kommen immer dann zustande, wenn der Anwender eine URL eingibt, auf einen Hyperlink klickt oder ein HTML-Formular mit GET im method-Attribut abschickt. Der andere gebräuchliche Request ist POST. Er wird von HTML-Formularen mit POST im method-Attribut verwendet. Zum Beispiel:

<form action="someServlet" method="POST">
...Formular-Inhalt
</form>

Um POST-Anfragen zu bearbeiten, muß Ihr Servlet nur die Methode doPost( ) anstelle von doGet( ) überschreiben. Jede dieser Methoden hat zwei Parameter: HttpServletRequest und HttpServletResponse. Die Anfrage enthält Informationen vom Client für das Servlet, welches über die Antwort Daten zurück an den Client schicken kann. Dies entspricht der Anfrage-Antwort-Natur des HTTP-Protokolls selbst. Das folgende Beispiel zeigt den kompletten Source Code für unser einfaches Servlet.

Beispiel: SplashScreenServlet.java

package chap6;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/**
 * Ein einfaches Servlet-Beispiel, das ein "Testbild"
 * für eine Webanwendung darstellt.
 */
public class SplashScreenServlet extends HttpServlet {
  public String getServletInfo( ) {
    return "Stellt ein Testbild dar.";
  }
  
  protected void doGet(HttpServletRequest request,
             HttpServletResponse response)
    throws IOException, ServletException {
      
    // hole Parameter aus dem Request
    String nextURL = request.getParameter("nextURL");
    if (nextURL == null) {
      nextURL = "/";
    }
  
    response.setContentType("text/html");
    PrintWriter pw = response.getWriter( );
    pw.println("<html>");
    pw.println("<head><title>Testbild</title></head>");
    pw.println("<body>");
  
    pw.println("<div align='center' style='border: 1px navy solid;'>");
    pw.println("<h1>Willkommen zu Java und XSLT</h1>");
    pw.println("<h3>O'Reilly und Partner</h3>");
    pw.println("<p>Erste Ausgabe, 2002</p><hr>");
    pw.println("<a href='" + nextURL + "'>Hier klicken, um fortzufahren...</a>");
    pw.println("</div>");
    pw.println("</body>");
    pw.println("</html>");
  }
}

Wir beginnen mit den import-Anweisungen. Die Servlet-API befindet sich in den Paketen javax.servlet und javax.servlet.http. Diese sind kein Bestandteil der Java 2 Standard Edition, sondern nur der Java 2 Platform Enterprise Edition. Es sind zwar viele Servlet-Implementierungen verfügbar, aber Apaches Tomcat ist die von Sun offiziell unterstützte Referenzimplementierung. Alle Beispiele in diesem Buch arbeiten mit der Version 4.0 von Tomcat und sollten auch mit jeder anderen verträglichen Servlet-Implementierung funktionieren.

Wie obige Abbildung zeigt, ist SplashScreenServlet eine Unterklasse von HttpServlet. Die erste Methode, die wir überschreiben, ist getServletInfo( ). Sie gibt eine kurze Beschreibung des Servlets zurück. Obwohl es nur eine Option ist, geben viele Servlet-Container diesen Text in ihrer Administrationskonsole aus.

In der Methode doGet( ) werden alle Clientanfragen bearbeitet. Diese Methode muß sicher mit Threads umgehen, denn es können potentiell viele Clients mit einer Servlet-Instanz arbeiten und doGet( ) nebenläufig abarbeiten. Ihnen ist vielleicht aufgefallen, daß doGet( ) als protected deklariert ist. Die Abarbeitungsreihenfolge ist die folgende:

  1. Der Servlet-Container ruft die service( )-Methode von HttpServlet auf.
  2. HttpServlet ermittelt den Anfragetyp (GET, POST, ...).
  3. HttpServlet ruft die entsprechende Methode auf (doGet( ), doPost( ), ...).

Weil die Methode doGet( ) von der Basis-Klasse aufgerufen wird, kann sie protected deklariert werden. Wenn die Methode doGet( ) nicht überschrieben wird, liefert HttpServlet eine Fehlerseite. Falls Sie auch eine POST-Anfrage bearbeiten wollen, müssen Sie die Methode doPost( ) überschreiben. Es ist gebräuchlich, in der Methode doGet( ) die Methode doPost( ) aufzurufen oder umgekehrt. Das Servlet kann so GET- und POST-Anfragen unterstützen, ohne daß Code dupliziert werden muß.

Die Implementierung von doGet( ) ist relativ einfach. Als erstes wird die Existenz des Parameters nextURL geprüft. Dieser ist Teil der Anfrage vom Browser an das Servlet. Wenn Sie zum Beispiel die folgende URL in Ihrem Browser eingeben, wird der Parameter nextURL mit angefügt:

"http://localhost:8080/chap6/splash?nextURL=http://www.oreilly.com"

Wenn dieser Parameter nicht angegeben wird, ist sein Wert null. Deshalb müssen Servlets immer auf null prüfen, wenn Sie Parameter aus Requests extrahieren:

String nextURL = request.getParameter("nextURL");
if (nextURL == null) {
   nextURL = "/";
}

In unserem Beispiel führt null zu einem Fehler, weshalb wir nextURL mit einem Slash (/) ersetzen. Das ist eine relative URL, die auf das Wurzelverzeichnis verweist. Falls das Servlet unter Tomcat ausgeführt wird, verweist das Wurzelverzeichnis auf die Homepage von Tomcat, nicht zu verwechseln mit dem Wurzelverzeichnis Ihres Dateisystems. In Tomcat befindet sich das Wurzelverzeichnis unter TOMCAT_HOME/webapps/ROOT, wobei TOMCAT_HOME das Installationsverzeichnis von Tomcat ist.

Mit der Methode getParameter( ) können auch die Werte eines HTML-Formulars ausgelesen werden. Wenn ein HTML-Formular abgeschickt wird, sollte jede Komponente eine Bezeichnung, wie Vorname oder Nachname, haben. Das Servlet ermittelt die Werte durch einen Aufruf von request.getParameter( ) für jedes Formularelement. Sie sollten die Parameter immer auf null prüfen und Whitespace entfernen. Wenn ein Formularelement fehlt, ist der entsprechende Parameter null, was entweder ein Hinweis auf einen Fehler in Ihrem HTML-Code oder ein absichtlicher Angriff auf ihre Website sein kann.

Die Klasse HttpServletResponse bietet Zugriff auf PrintWriter und OutputStream und damit die Möglichkeit, Text und Binärdaten an den Client zu schicken. Verwenden Sie für HTML- und XML-Daten die Methode HttpServletResponse.getWriter( ) und für Bilder und andere Binärdaten HttpServletResponse.getOutputStream( ). Beachten Sie bitte auch, daß der Content-Type der Antwort vor dem Erzeugen des Writers gesetzt wird:

response.setContentType("text/html");
PrintWriter pw = response.getWriter( );

Das ist wichtig, da die HTTP-Antwort aus einem Header und dem anschließenden eigentlichen Inhalt besteht. Der Content-Type ist einer der Header-Parameter und muß deshalb vor den Daten gesetzt werden. Ohne zu sehr ins Detail zu gehen, ist es immer ratsam, den Content-Type vor dem Erzeugen des Writers zu setzen. Wir werden in Beispielen gelegentlich text/xml als Content-Type verwenden, aber nur, wenn wir reine XML-Daten zum Client schicken.

Der Rest von SplashScreenServlet gibt einfach eine HTML-Antwort aus:

pw.println("<html>");
pw.println("<head><title>Testbild</title></head>");
pw.println("<body>");

pw.println("<div align='center' style='border: 1px navy solid;'>");
pw.println("<h1>Willkommen zu Java und XSLT</h1>");
pw.println("<h3>O'Reilly und Partner</h3>");
pw.println("<p>Erste Ausgabe, 2002</p><hr>");
pw.println("<a href='" + nextURL + "'>Hier klicken, um fortzufahren...</a>");
pw.println("</div>");
pw.println("</body>");
pw.println("</html>");

Wie Sie sehen, wird der Parameter nextURL verwendet, um einen Hyperlink zur nächsten Seite zu erzeugen. Deshalb ist es wichtig, auf null zu prüfen. Der hier gezeigte Ansatz ist für einfache Beispiele adäquat, wird aber bei komplexen Webseiten schnell unübersichtlich, weil diese oft hunderte, wenn nicht gar tausende Zeilen HTML-Code benötigen, um Tabellen, Farben und Graphiken zu erzeugen. Aus den Gründen, die schon unter XSLT-Verarbeitung mit Java besprochen wurden, ist es in komplexen Webanwendungen inakzeptabel, den HTML-Code im Servlet zu verankern.

   

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Java & XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2002 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Java und XSLT" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de