Traditionelle Lösungsansätze

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

Bevor wir uns in komplexere Optionen stürzen, lassen Sie uns einen Schritt zurück machen und ein paar grundlegende Lösungsansätze für die Webentwicklung mit Java betrachten. Für kleine Webanwendungen oder begrenzt dynamische Seiten sind diese Methode durchweg ausreichend. Sie werden aber schon richtig vermuten, daß keine dieser Vorgehensweisen mit XML und XSLT mithalten kann, wenn die Sites komplexer werden.

CGI

Das Common Gateway Interface (CGI) ist ein Schnittstellenprotokoll zur Anbindung von in nahezu jeder beliebigen Sprache geschriebenen, externen Anwendungen an einen Webserver. Die gebräuchlichsten für CGI verwendeten Sprachen sind C und Perl. Die Schnittstelle wird dabei, abhängig von der Art der Anfrage, auf verschiedene Arten realisiert. Bei einem HTTP GET-Request werden die Parameter beispielsweise über die Umgebungsvariable QUERY_STRING an das CGI-Skript übergeben. HTTP POST-Daten werden dagegen an die Standardeingabe des CGI-Skripts übergeben. CGI sendet seine Ergebnisse generell über die Standardausgabe an den Webserver zurück.

Gewöhnliche CGI-Programme werden vom Webserver aus als externe Programme aufgerufen. Das ist auch der auffälligste Unterschied, verglichen mit Servlets. Mit jeder Anfrage des Browsers startet der Webserver einen neuen Prozeß zur Ausführung des CGI-Programms. Neben den offensichtlichen Performance-Nachteilen macht es dieses Vorgehen schwierig, Statusinformationen zwischen den Anfragen aufrechtzuerhalten. Ein Web-basierter Warenkorb stellt ein perfektes Beispiel für Statusinformationen dar, die zwischen Requests aufrechterhalten werden müssen. Die folgende Abbildung illustriert den CGI-Prozeß.

Abbildung: CGI-Prozess

Abbildung: CGI-Prozeß

Hinweis:
FastCGI stellt eine Alternative zu CGI mit zwei wichtigen Unterschieden dar. Erstens enden FastCGI-Prozesse nicht nach jedem Request-Response-Zyklus. Zweitens wurden die Umgebungsvariablen und Pipe I/O-Mechanismen zu Gunsten der TCP-Verbindungen entfernt, weshalb FastCGI-Programme auf verschiedene Server verteilt werden können. Im Ergebnis eliminiert FastCGI die schlimmsten Nachteile von CGI und erleichtert so die Weiterverwendung von bestehenden CGI-Programmen.

Obwohl technisch die Möglichkeit besteht, ist es keine gute Idee, Java für die CGI-Programmierung zu nutzen. Genaugenommen ist es eine schreckliche Idee! Die Java Virtual Machine (JVM) müßte für jede einzelne Anfrage gestartet werden, was die Sache schmerzhaft langsam machen würde. Jeder Java-Programmierer weiß, daß die Startzeit einer Anwendung sicher nicht zu den Stärken von Java gehört. Die Servlet-Technologie mußte sich damit als erstes auseinandersetzen. Was gebraucht wurde, war eine neue Möglichkeit, die JVM einmal zu starten und sie laufen zu lassen, auch wenn keine Anfragen gemacht werden. Der Begriff Servlet Engine bezeichnet diese JVM, die die Servlets hostet, oftmals in doppelter Funktion als HTTP-Webserver.

Servlets als CGI-Ersatz

Suns Java Servlet API wurde ursprünglich 1997 veröffentlicht, als Java hauptsächlich noch eine Sprache für die clientseitige Entwicklung war. Servlets wurden damals als Ersatz für CGI-Programme vermarktet und auch genutzt. Die Entwicklergemeinde hat die Servlets dann aufgrund ihrer Vorteile gegenüber CGI auch ziemlich schnell angenommen.

Da die Servlet Engine so lange läuft wie der Webserver, können Servlets einmal in den Speicher geladen werden und dort für folgende Anfragen verbleiben. Das läßt sich in Java leicht bewerkstelligen, denn Servlets sind tatsächlich nichts anderes als Java-Klassen. Die JVM lädt die Servlet-Objekte einfach in den Speicher und hält an den Referenzen fest, solange die Webanwendung läuft.

Die Beständigkeit von Servlets führt zu zwei weiteren Vorteilen, die Servlets weit über die Fähigkeiten von CGI hinausbefördern. Erstens können Statusinformationen für lange Zeit im Speicher vorgehalten werden. Obwohl der Browser seine Verbindung zum Webserver mit jedem Request-Response-Zyklus verliert, können Servlets Objekte im Speicher ablegen, bis der Browser sich für die nächste Seite erneut verbindet. Zweitens können mehrere Clients sich dieselbe Servlet-Instanz teilen, da Java über Threading-Funktionalität verfügt. Da der Einsatz mehrerer Threads wesentlich effizienter ist, als mehrere Prozesse zu erzeugen, bieten Servlets sehr gute Performance.

Frühe Versionen der Java Servlet API boten noch keine Deployment-Mechanismen, also Mechanismen zur Installation auf einem Server. Trotz konsistenter Servlet-API war die Installation auf unterschiedlichen Servlet-Engines vollständig anbieterabhängig. Mit Version 2.2 der API blieben dann die proprietären Servlet-Engines zugunsten einer kompatiblen Servlet Container-Spezifikation auf der Strecke. Die Idee eines Containers ist die formelle Beschreibung der Beziehung zwischen einem Servlet und der Umgebung, in der es sich befindet. Das machte es möglich, dasselbe Servlet ohne Änderung in den Containern jedes Anbieters einzusetzen.

Mit dem Servlet-Container kam auch das Konzept einer Webanwendung. Eine Webanwendung besteht aus einer Reihe von Servlets, statischen Webdokumenten, Bildern und/oder jeder anderen benötigten Ressource. Standardmäßig werden solche Webanwendungen mit einer WAR-Datei (Webanwendungsarchiv) eingesetzt, wobei es sich um eine JAR-Datei (Java-Anwendungsarchiv) mit Standardverzeichnisstruktur handelt, die .war als Dateinamenerweiterung hat. Man nimmt tatsächlich auch das jar-Kommando, um WAR-Dateien zu generieren. Zusammen mit der WAR-Datei kommt ein sogenannter Deployment-Deskriptor, was nichts anderes ist als eine XML-Konfigurationsdatei, die alle Konfigurationsaspekte einer Webanwendung festlegt. Die wichtigen Details von WAR-Dateien und Deployment-Deskriptoren werden unter Servlet-Grundlagen und XSLT skizziert.

Servlets sind leicht zu implementieren, portierbar, können in konsistenter Weise in jedem Servlet-Container eingesetzt werden und bieten hohe Performance. Wegen dieser Vorteile sind Servlets die zugrundeliegende Technologie für jeden anderen Ansatz in diesem Kapitel. Werden sie isoliert eingesetzt, haben auch Servlets Beschränkungen. Diese Beschränkungen offenbaren sich mit zunehmender Komplexität von Webanwendungen.

Der folgende Screenshot zeigt eine einfache Webseite, die die Fernsehsendungen für den aktuellen Tag auflistet. In dieser ersten Implementierung wird ein Servlet verwendet. Weiter hinten in diesem Kapitel folgt dann eine JavaServer Pages (JSP)-Implementierung.

Abbildung: Ausgabe von TVProgrammServlet

Abbildung: Ausgabe von TVProgrammServlet

Die Java-Klasse Programmuebersicht verfügt über eine Methode getHeutigeSendungen( ), die ein Feld von Sendung-Objekten zurückliefert. Das Feld ist bereits sortiert, was den Arbeitsaufwand zur Erzeugung der Seite für das Servlet reduziert. Die Klassen Programmuebersicht und Sendung werden auch in den weiteren Beispielen in diesem Kapitel verwendet. Idealerweise wird das helfen zu zeigen, daß, egal nach welcher Methode Sie vorgehen, die Auslagerung von Anwendungslogik und Code zum Datenbankzugriff aus dem Servlet den Wechsel zu neuen Technologien, ohne alles neu schreiben zu müssen, leichter macht. Den Quelltext für TVProgrammServlet.java sehen Sie im folgenden Beispiel. Die Erzeugung der Ausgaben über eine Reihe von println( )-Statements ist typisch für ein Servlet der ersten Generation.

Beispiel: TVProgrammServlet.java

package kapitel4;

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

public class TVProgrammServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,
      HttpServletResponse response) throws IOException,
      ServletException {
      
    SimpleDateFormat datumFmt = new SimpleDateFormat("HH:mm");
        
    Sendung[] sendungen = Programmuebersicht.getInstance().getHeutigeSendungen( );
        
    response.setContentType("text/html");
    PrintWriter pw = response.getWriter( );
    pw.println("<html><head><title>Die heutigen Sendungen</title></head><body>");
    pw.println("<h1>Die heutigen Sendungen</h1>");
    pw.println("<table border=\"1\" cellpadding=\"3\"");
    pw.println(" cellspacing=\"0\">");
        
    pw.println("<tr><th>Kanal</th><th>von</th>");
    pw.println("<th>bis</th><th>Titel</th></tr>");
        
    for (int i=0; i<sendungen.length; i++) {
      pw.println("<tr>");
      pw.print("<td>");
      pw.print(sendungen[i].getKanal( ));
      pw.println("</td>");
      pw.print("<td>");
      pw.print(datumFmt.format(sendungen[i].getAnfangUhrzeit( )));
      pw.println("</td>");
      pw.print("<td>");
      pw.print(dateFmt.format(sendungen[i].getEndeUhrzeit( )));
      pw.println("</td>");
      pw.print("<td>");
      pw.print(sendungen[i].getTitel( ));
      pw.println("</td>");
      pw.println("</tr>");
    }
    pw.println("</table>");
    pw.println("</body>");
    pw.println("</html>");
  }
}

Wenn Sie an den Details der Servlet-Programmierung interessiert sind, sollten Sie auf jeden Fall das Kapitel Servlet-Grundlagen und XSLT lesen. Im Moment konzentrieren wir uns auf die Art, wie hier HTML erzeugt wird. Die zahlreichen println( )-Statements sehen in diesem kurzen Beispiel recht harmlos aus, aber eine »echte« Webseite wird tausende solcher println( )-Statements enthalten und so die Pflege des Codes über die Jahre schwermachen. Generell möchte man diesen Code in eine Reihe von Methoden und Objekten aufteilen, die jeweils Teile des HTML ausgeben. Aber auch diese Methode ist mühselig und fehleranfällig.

Hauptprobleme sind die Skalierbarkeit der Entwicklung und deren zukünftige Pflege. Mit zunehmender Komplexität der Seiten wird der Code immer schwerer zu schreiben, und es wird schwerer, Änderungen am HTML-Code zu machen, wenn neue Anforderungen bestehen. Online-Redakteure und Grafikdesigner sind aus dem Prozeß ausgeschlossen, weil nur ein Programmierer den Code erzeugen und modifizieren kann. Bei jeder kleinen Änderung müssen die Programmierer die Anwendung neu kompilieren, testen und im Servlet-Container installieren.

Jenseits der anstrengenden Natur der HTML-Erzeugung tendieren die Servlets erster Generation dazu, zuviel zu tun. Es ist nicht klar, wo Fehlerbehandlung, Formularverarbeitung, Anwendungslogik und HTML-Erzeugung sich befinden sollen. Obwohl wir in der Lage sind, die Liste der Sendungen mit zwei Hilfsklassen zu erzeugen, ist für komplexe Webanwendungen eine rigorosere Vorgehensweise erforderlich. Alle übrigen in diesem Kapitel präsentierten Technologien sind so ausgelegt, daß Sie eins oder mehrere dieser Probleme berücksichtigen, was um so wichtiger wird, je weiter eine Webanwendung entwickelt ist.

JSP

Zweifelsohne haben Sie schon von JSP (JavaServer Pages) gehört. Im Moment ist JSP eine heiße Sache in der Webentwicklung, mit vollmundigen Behauptungen bezüglich der Produktivitätssteigerung. Das Argument ist simpel: Statt HTML in Java-Servlets einzubetten, was Java-Programmierer erfordert, kann man doch auch mit statischem HTML anfangen! Danach fügt man dem HTML ein paar spezielle Tags hinzu, die dann von der JSP-Engine dynamisch erweitert werden, und erzeugt so eine dynamische Webseite. Das folgende Beispiel enhält ein ganz einfaches JSP-Beispiel, das exakt dieselbe Ausgabe wie das TVProgrammServlet erzeugt.

Beispiel: TVProgramm.jsp

<%@ page import="kapitel4.*,java.text.*" %>
<%! SimpleDateFormat datumFmt = new SimpleDateFormat("HH:mm"); %>
<html>
    <head>
        <title>Die heutigen Sendungen</title>
    </head>
    <body>
        <h1>Die heutigen Sendungen</h1>
        <% Sendung[] sendungen = Programmuebersicht.getInstance().getHeutigeSendungen( ); %>
        <table border="1" cellpadding="3" cellspacing="0">
            <tr><th>Kanal</th><th>Von</th><th>Bis</th><th>Titel</th></tr>
            <% for (int i=0; i<sendungen.length; i++) { %>
            <tr>
                <td><%= sendungen[i].getKanal( ) %></td>
                <td><%= datumFmt.format(sendungen[i].getAnfangUhrzeit( )) %></td>
                <td><%= datumFmt.format(sendungen[i].getEndeUhrzeit( )) %></td>
                <td><%= sendungen[i].getTitel( ) %></td>
            </tr>
            <% } %>
        </table>
    </body>
</html>

Wie TVProgramm.jsp zeigt, ist der größte Teil der JSP-Seite statisches HTML, hier und da gespickt mit einigen speziellen JSP-Tags für dynamischen Inhalt. Bei der ersten Anfrage eines Clients wird die komplette JSP-Seite in den Quelltext für ein Servlet übersetzt. Der generierte Servlet-Quelltext wird dann kompiliert und zur Verwendung für folgende Anfragen in den Speicher geladen. Während des Übersetzungsprozesses werden die JSP-Tags durch dynamische Inhalte ersetzt, damit der aufrufende Benutzer die HTML-Ausgabe so sieht, als wäre die ganze Seite statisch.

Die Laufzeit-Performance von JSP ist vergleichbar mit manuell erstellten Servlets, weil der statische Inhalt der JSP-Seite im generierten Servlet-Quelltext durch eine Reihe von println( )-Statements ersetzt wird. Der einzige große Performance-Tiefschlag trifft denjenigen, der die JSP-Seite zuerst aufruft, denn dann muß diese ja in ein Servlet übersetzt und dieses dann kompiliert werden. Die meisten JSP-Container bieten aber Optionen zur Vermeidung dieses Problems, indem sie die JSP-Seite vorkompilieren.

Die Fehlersuche kann in JSP zu einer echten Herausforderung werden. Da JSP-Seiten maschinell in Java-Klassen übersetzt werden, sind die Methoden-Signaturen und Klassennamen nicht immer wirklich intuitiv. Wenn ein Programmierfehler auftritt, werden Sie häufig mit schrecklichen Stack-Traces konfrontiert, die Ihnen direkt im Browser angezeigt werden. Sie können optional eine Fehlerseite angeben, die immer angezeigt werden soll, wenn ein unerwarteter Zustand auftritt. Das ergibt zwar eine benutzerfreundliche Fehlermeldung, hilft Ihnen jedoch herzlich wenig bei der Diagnose des Problems.

Hier ist ein Ausschnitt dessen, was der Apache Tomcat im Webbrowser anzeigt, wenn man versehentlich die schließende geschweifte Klammer (}) aus der For-Schleife im vorigen JSP-Beispiel wegläßt:

A Servlet Exception Has Occurred
org.apache.jasper.JasperException: Unable to compile class for
JSP..\work\localhost\kapitel4\_0002fTVProgramm_0002ejspTVProgramm_jsp_2.java:104:
'catch' without 'try'.
     } catch (Throwable t) {
      ^
..\work\localhost\kapitel4\_0002fTVProgramm_0002ejspTVProgramm_jsp_2.java:112:
'try' without 'catch' or 'finally'.
}
^
..\work\localhost\kapitel4\_0002fTVProgramm_0002ejspTVProgramm_jsp_2.java:112:
'}' expected.
}
^
3 errors

at org.apache.jasper.compiler.Compiler.compile(Compiler.java:294)
at org.apache.jasper.servlet.JspServlet.doLoadJSP(JspServlet.java:478)
... der Rest des Stack-Trace wird hier ausgelassen

Der Rest des Stack-Trace ist nicht sehr hilfreich, weil er nur Tomcat-interne Methoden aufführt. _0002fTVProgramm_0002ejspTVProgramm_jsp_2 ist der Name der generierten Servlet-Klasse. Die Zeilenangaben beziehen sich auf Positionen in diesem generierten Code und nicht auf die JSP-Seite selbst.

Das direkte Einbetten von HTML in Servlets ist nicht empfehlenswert, weil das HTML dann nur von einem Programmierer gewartet werden kann. In JSP betten Sie allerdings oftmals Java-Code in HTML ein. Obwohl die Einbettung hier umgekehrt ist, haben Sie immer noch keine saubere Trennung zwischen HTML-Erzeugung und Anwendungslogik. Denken Sie nur an die Probleme, auf die Sie stoßen, wenn die Logik in einer JSP-Seite über eine einzelne Seite hinausgeht. Möchten Sie wirklich hunderte Java-Codezeilen durchmischt mit HTML und umgeben von diesen hübschen <% %>-Tags? Leider haben viel zu viele JSP-Seiten den hautpsächlichen Teil ihres Java-Codes direkt im HTML eingebettet.

Die ersten Versionen von JSP boten keine wirklich wasserdichten Möglichkeiten, um Java-Code und HTML zu trennen. Obwohl JavaBeans-Tags als Möglichkeit angeboten wurden, einigen Java Code zu entfernen, war der Grad der Komplexität sehr begrenzt. Diese JavaBeans-Tags ermöglichen JSP-Seiten, mit Hilfsklassen zu interagieren, die konform zu Suns JavaBeans API geschrieben sind. Gegenwärtige Trends in der JSP-Spezifikation haben grundsätzliche Verbesserungen eingeführt. Der größte Schub kam mit den benutzerspezifischen Tags (technisch betrachtet, erzeugen Programmierer Aktionen, die über benutzerspezifische JSP-Tags einbezogen werden), die nun endlich gestatten, den Java-Code aus den Seiten zu entfernen. Eine Webseite mit benutzerspezifischen Tags könnte so aussehen wie im folgenden Beispiel dargestellt.

Beispiel: JSP mit benutzerspezifischen Tags

<%@ taglib uri="/meine_taglib" prefix="abc" %>
<html>
    <head>
        <title>JSP Tag-Library Demonstration</title>
    </head>
    <body>
        <abc:standardKopfzeile/>
        <abc:firmenLogo/>
        <h1>aktuelle Mitteilungen</h1>
        <abc:mitteilungen filter="aktuell"/>
        <h1>Jobangebote</h1>
        <abc:jobAngebote abteilung="alle"/>
        <abc:standardFusszeile/>
    </body>
</html>

Wie Sie sehen, sind die benutzerspezifischen Tags normale XML-Tags mit einem Namensraum-Präfix. Namensraum-Präfixe werden verwendet, um XML-Tags eindeutige Namen zu geben. Weil Sie das Präfix für jede Tag-Bibliothek wählen können, ist es kein Problem, Bibliotheken verschiedener Anwender zu nutzen, ohne Namenskonflikte befürchten zu müssen. Die Tags werden auf Java-Klassen abgebildet, sogenannte Tag-Handler, die für die eigentliche Arbeit zuständig sind. Die JSP-Spezifikation begrenzt dabei nicht die zugrundeliegende Java-Implementierung, so daß andere Sprachen verwendet werden können, wenn der JSP-Container es unterstützt. Mit den benutzerdefinierten Tags können die Programmierer in Ihrer Firma eine Sammlung von getesteten Tags zur Erzeugung von Firmenlogos, Suchmasken, Navigationsleisten und Seitenfußzeilen produzieren. Nicht-Programmierer, die sich auf das HTML-Layout konzentrieren, können den zugrundeliegenden Tag-Handler-Code getrost vergessen. Der größte Nachteil dieser Methode ist das Fehlen von standardisierten Tags. Obwohl verschiedene Open Source-Projekte damit beschäftigt sind, benutzerspezifische Tag-Bibliotheken zu entwickeln, ist es unwahrscheinlich, daß für jede Anforderung ein Tag existieren wird.

Ein beständiges Problem eines reinen JSP-Ansatzes ist die komplexe Validierung. Obwohl JSP mit benutzerdefinierten Tags eine ideale Methode für ausschließlich anzeigende Seiten ist, ist sie nicht geeignet zur Validierung der Eingabedaten aus einem komplexen HTML-Formular. In dieser Situation ist es fast unvermeidlich, daß Java-Code – wahrscheinlich sogar eine ganze Menge davon – sich in die Seite einschleicht. Hier ist eine Hybridlösung (JSP und Servlets), die im nächsten Abschnitt zur Sprache kommt, wünschenswert.

Im Vergleich zu einem XML/XSLT-Ansatz erfordert JSP wesentlich mehr Mühe, um die Darstellung sauber von den zugrundeliegenden Daten und der Anwendungslogik zu trennen. Bei hauptsächlich statischen Websites kann JSP für Nicht-Programmierer leicht zu erstellen sein, da sie dann direkt im HTML arbeiten. Wenn aber die dynamischen Inhalte Überhand nehmen, bestehen die Möglichkeiten im Einbetten von Java-Code in die JSP-Seiten, in der Erzeugung von benutzerdefinierten Tags oder im Erstellen von Java-Beans, die HTML-Fragmente ausgeben. Das Einbetten von Code in die JSP-Seiten ist, wegen der häßlichen Syntax und den Schwierigkeiten bei Wartung und Pflege, nicht zu empfehlen. Die anderen Möglichkeiten verbergen zwar den Code vor dem JSP-Autor, ein Teil Ihrer Webanwendung gibt aber immer HTML aus Java-Code heraus aus, entweder in benutzerdefinierten Tags oder in JavaBeans-Komponenten.

Eine weitere Schwäche von JSP-Seiten, verglichen mit XML und XSLT, offenbart sich, wenn Sie versuchen, Ihre Webanwendung zu testen. Es praktisch unmöglich, den JSP-Code außerhalb eines Webservers mit Servlet-Container zu testen. Um eine einfache automatisierte Testroutine für JSP zu schreiben, müssen Sie einen Webserver starten und Ihre JSPs via HTTP-Requests aufrufen. Mit XML und XSLT hingegen können Sie die XML-Daten programmgesteuert generieren, und zwar ganz ohne Webbrowser oder -server. Diese XML-Daten können dann gegen eine DTD oder ein Schema validiert werden. Die XSLT-Stylesheets können Sie mit Kommandozeilen-Tools testen, ohne Sie in einen Servlet-Container einzusetzen oder einen Webserver zu starten. Wenn Sie dann noch XHTML statt HTML verwenden, kann das Ergebnis der Transformation sogar mit einer DTD validiert werden.

Template-Engines

Lassen Sie uns, bevor wir weitermachen, über Template-Engines sprechen. Eine schnelle Suche im Internet zeigt, daß es solche Template-Engines zuhauf gibt, wobei jede für sich in Anspruch nimmt, aus verschiedenen Gründen besser als JSP zu sein. Größtenteils haben Template-Engines eine Menge mit JSP gemeinsam, besonders, wenn man sich auf benutzerdefinierte Tags beschränkt. Einige Unterschiede gibt es trotzdem:

  • Template-Engines verbieten normalerweise die Einbettung von Java-Code in Seiten. Obwohl JSP es erlaubt, ist das Vermischen von Java-Code und HTML keine gute Vorgehensweise.
  • Die meisten Template-Engines sind nicht kompiliert, deswegen haben sie nicht das Problem, das JSP mit Fehlermeldungen hat. Sie starten außerdem schneller beim ersten Aufruf, was die Entwicklung leichter machen kann. Die Auswirkungen auf den Benutzer sind minimal. Um die Template-Engines zu betreiben, braucht man ebenso wie bei JSP einen Java-Compiler auf dem Webserver.
  • Template-Engines haben eine existierende Bibliothek von Tags und/oder einfachen Skriptsprachen. JSP hat keine Standard-Tags, obwohl unzählige Bibliotheken von anderen Anbietern und aus Open Source-Projekten verfügbar sind. Die JSP-API ist offen, daher kann man mit wenig Aufwand eigene Tags erzeugen. Template-Engines haben ihre eigenen Mechanismen zur Integration des zugrundeliegenden Java-Codes.
  • JSP hat die Unterstützung von Sun und ist problemlos mit jedem Servlet-Container einsetzbar. Der Hauptvorteil eines »Standards« ist die hohe Verfügbarkeit von Dokumentationen, Fachleuten und Beispielen. Es gibt viele JSP-Implementierungen, aus denen man auswählen kann.

Der Hybrid-Ansatz

Da JSP nun benutzerdefinierte Tags hat, können Sie den kompletten Java-Code entfernen (bzw. eigentlich nur verstecken), wenn eine Seite zum Versenden an den Browser erzeugt wird. Wird ein komplexes HTML-Formular an JSP geschickt, gibt es jedoch immer noch Probleme. Sie müssen sicherstellen, daß alle Felder vorhanden sind, prüfen, ob die Daten innerhalb ihrer gültigen Grenzen sind, und die Daten von Null-Werten und überflüssigen Leerzeichen befreien. Die Überprüfung ist nicht besonders schwierig, kann aber mühselig sein und erfordert viel benutzerspezifischen Code. Diesen Code möchten Sie aber aus Gründen der Überschaubarkeit bei Fehlersuche und Wartung nicht direkt in die JSP-Seite einbetten.

Die Lösung ist ein Hybrid-Ansatz, in dem ein Servlet mit einer JSP-Seite zusammenarbeitet. Die Servlet-API hat eine hilfreiche Klasse namens RequestDispatcher, die serverseitige Weiterleitung und Einschließen von externem Code ermöglicht. Das ist der normale Mechanismus zur Interaktion des Servlets mit JSP. Die folgende Abbildung zeigt die Vorgehensweise auf einem hohen Level.

Abbildung: Hybrider JSP/Servlet-Ansatz

Abbildung: Hybrider JSP/Servlet-Ansatz

Diese Methode kombiniert die Vorteile von Servlets mit denen von JSPs. Die Pfeile zeigen den Kontrollfluß, wenn der Browser eine Anfrage stellt. Die Aufgabe des Servlets ist es, die Anfrage abzufangen und zu überprüfen, ob die Formulardaten korrekt sind. Danach übergibt es die Kontrolle an eine geeignete JSP-Seite. Die Kontrolldelegation geschieht über javax.servlet.RequestDispatcher, einem Standardbestandteil der Servlet-API. Die JSP-Seite gibt dann nur noch die Seite wieder, idealerweise mittels benutzerspezifischen Tags und ohne mit HTML vermischten Java-Code zu enthalten.

Das Hauptproblem dieser Methode offenbart sich, wenn Ihre Website beginnt, über ein paar Seiten hinauszuwachsen. Sie müssen sich dann zwischen einem großen Servlet, das alle Anfragen abfängt, einem separaten Servlet pro Seite oder Hilfsklassen, verantwortlich für die Verarbeitung einzelner Seiten, entscheiden. Das ist zwar keine technische Herausforderung, dafür aber ein Problem der Organisation und Konsistenz. Hier können Web-Frameworks hilfreich sein.

   

<< 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