wtp+tomcat – Tutorial #3: (Tag-)Libraries und Präsentation

Rückblick: In den vorangegangenen beiden Teilen dieses Tutorials hatten wir eine grundlegende Dynamic Web Project – Struktur auf Basis einer Apache Tomcat-Umgebung angelegt, Code in Form von JSPs respektive Servlets eingefügt und einen Blick darauf geworfen, wie man dieses Projekt auf einem lokal installierten Tomcat-Container ausgeführt bekommt. Damit läßt sich schon sehr viel anstellen, allerdings folgen aus den beiden Teilen (mindestens) zwei grundlegende Erkenntnisse:

  • In der dargestellten Form führt auch die JEE-Web-Schicht in die Code-“Hölle”, weil wir entweder Servlets mit eingewobenem XHTML oder JSPs vermengt mit Java-Code bauen. Grundsätzlich lösbar, aber keine wirklich hübsche Angelegenheit, wie sich spätestens bei der ersten Wartung eines größeren Projektes zeigen wird.
  • Einer der gravierenden Vorteile, der für die Verwendung von Java auch für Web-Anwendungen (oder web-basierte Frontends auf JEE-Anwendungen) spricht, ist die einen fast schon erschlagende Menge an Bibliotheken, die sehr viel Funktionalität “ready-to-use” bereitstellen und den Aufwand der Implementation bestimmter Anforderungen angenehm minimieren können.

Beide Probleme in einem Schlag zu lösen und nebenbei noch ein paar für die Java-Web-Entwicklung angenehme Features der Eclipse-IDE auszuprobieren soll Inhalt dieses dritten Teils sein…

Voraussetzungen

Wiederum gilt alles, was in den vorangegangenen Teilen zu diesem Thema gesagt wurde. Konkretisiert für die gegenwärtige Aufgabenstellung:

  • Obwohl nicht essentiell wichtig, hilft es für die Beispiele zu wissen, was es mit JAR-Dateien und dem CLASSPATH unter Java auf sich hat.
  • Wissen um den Begriff “Tag” im Hinblick auf X(HT)ML ist essentiell, ebenso sollte klar sein, was es mit Attributen in diesem Kontext auf sich hat.
  • Es hilft, die verschiedenen Objekt-Scopes innerhalb von JSP-Pages und Servlets zumindest zu kennen. Grobe Infos dazu hat’s auf Wikipedia und in den SDN-Foren (auf englisch). Im Beispiel wird der request-Scope zum Einsatz kommen.
  • Zusätzlich zur allgemeinen Umgebung (Java, Eclipse, Tomcat) wird eine aktuelle Version der Jakarta Taglibs – Bibliothek benötigt. Diese kann hier heruntergeladen und sollte an eine Stelle extrahiert werden, an der man sie wiederfindet. 😉 (In meinem System liegen alle derartigen Pakete unter /opt/appsrv/frameworks/.)

Danach kann es eigentlich schon losgehen wie gehabt: Eclipse starten, Workspace öffnen, und für dieses Vorhaben sinnvollerweise ein neues Projekt anlegen (das meine im Beispiel nennt sich webstat).

Direktiven und Template
Vorweg: Eine jede Tag-Bibliothek, die innerhalb einer JSP Verwendung finden soll, muß dieser “bekanntgemacht” werden durch Verwendung einer taglib-Direktive, die einen Verweis auf die Beschreibung der Tags in der Bibliothek sowie die Definition eines XML-Präfix beinhaltet (welcher für die zugehörigen Tags im Markup-Code der JSP zum Einsatz kommt). Im simpelsten Fall (der Verwendung der JSTL-core-Bibliothek) hat diese Direktive die Form

<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>.

Um dies für zukünftige JSPs schnell griffbereit zu haben, lohnt es sich, den Templates-Mechanismus des WTP zu verwenden, der über “Preferences” -> “Web and XML” -> “JSP Files” -> “JSP Templates” erreichbar ist:

Template-Preferences

Über “New” können wir ein neues Template zur Verwendung in JSP-Dateien anlegen, was wir dann auch tun wollen:

Template anlegen

“Name” und “Description” sind frei wählbar (und sollten sinnvollerweise mit aussagekräftigen Werten befüllt werden); für “Context” wählen wir “JSP Tag”, und in “Pattern” fügen wir die vorangehend bereits genannte Taglib-Direktive für die core-Bibliothek ein.

Die View-Seite
Damit sind wir soweit erst einmal vorbereitet und können, analog Teil I, eine neue JSP-Seite anlegen, die wir view.jsp nennen.

Um die core-Bibliotheken in der Seite verwenden zu können, fügen wir mittels Template die vorher definierte Direktive ein, sinnvollerweise nach dem <@page ... -Tag zu Beginn der Seite auf eine neue Zeile. Die JSP-Templates, wie auch unser selbstdefiniertes, sind über die Code-Completion – Funktionalität ([CTRL]+[SPACE]) erreichbar:

Taglib-Direktive einfuegen

Daraufhin fügt die IDE, wenig überraschend, den Code-Schnipsel in die JSP aus der Vorlage ein,…

Taglib-Direktive

… und wir können die Tags aus core in unserer Server-Page verwenden. Als denn… 🙂

Tags und Code

In unserem (denkbar simplen) Beispiel wollen wir Tags aus core verwenden, um die Header des HTTP-Requests, den der Servlet-Container verarbeitet, auszugeben. Im Kern benötigen wir dabei zwei Elemente:

  • Wir wissen sicher, daß wir über mehr als ein Datenelement sprechen, mithin liegt es nahe, nach einer Art Schleife / Iteration zu suchen, in der die Ausgabe der Elemente behandelt wird. <c:forEach> ist hier das Werkzeug, dessen wir uns bedienen wollen.
  • Um wenig (möglichst keinen) Java-Code inline in der JSP zu halten, bedarf es dann natürlich einer Funktion, die die Ausgabe des Inhaltes eines (Java-)Objektes realisiert. Dafür steht uns <c:out> zur Verfügung.

Die entsprechenden Tags können wir nun in den HTML-Body der JSP einfügen, wobei uns wieder die IDE hilfreich zur Seite steht, indem sie uns sowohl die Tags selbst …

Tag-Completion

… als auch deren Attribute…

Tag-Attribute-Completion

… zu vervollständigen hilft. Im Endeffekt sollte der Code nach der Bearbeitung folgende Gestalt haben:

Tag-Code

Als äußerst knappe Erklärung hierzu: forEach iteriert über eine Java-Collection oder (analog zu for) über einen Integer-Bereich. Für den Fall einer Collection ist das entsprechende Objekt im Attribut items zu definieren; das jeweils aktuelle Element während der Iteration ist innerhalb der forEach-Schleife in der im Attribut var benannten Variable verfügbar, die out hier zur Ausgabe verwendet. Das via items referenzierte Objekt muß dabei innerhalb eines der Scopes verfügbar sein, die innerhalb der JSP existieren.

Damit ist die JSP für den minimalen Beispielfall auch schon fertig, und wir können uns der zweiten Aufgabe zuwenden, der Definition eines Servlets, welches für die Bereitstellung der Daten zur Darstellung sorgt.

Das Daten-Servlet

Analog zu Teil II erzeugen wir also ein neues Servlet, welches auf den Namen ViewServlet hören und über das Mapping /view erreichbar sein soll. im ersten Kontakt mit Servlets hatten wir die Mapping-Definition nach der Erzeugung durch Manipulation am Deployment-Deskriptor der Web-Anwendung manuell vorgenommen; hier wollen wir kurz überblicken, daß sich dies auch schon während der Erzeugung des Servlets realisieren läßt. Dafür gehen wir nach der grundlegenden Definition des Servlets…

View-Servlet

… mittels ‘Next’ in den nächsten Bildschirm des Assistenten, in dem der Bereich “URL Mappings” zu finden ist:

View-Servlet

Genau das suchen wir – also können wir mittels “Edit” das voreingestellte Mapping (/'Servletname') durch die von uns präferierte Definition ersetzen und das Servlet mit “Finish” erzeugen:

View-Servlet

Das Ergebnis überrascht nicht weiter – leeres Servlet, doGet(...)-Methode – wir wissen weitestgehend, was zu tun ist:

  • Innerhalb von doGet(...) müssen wir ‘irgendwie’ die vorher definierte JSP aufrufen, die unsere Inhalte anzeigen soll. Hier hilft uns ein RequestDispatcher.
  • Zweckmäßigerweise sollten wir zuvor Daten, die durch die JSP angezeigt werden können, in einer geeigneten Struktur verfügbar machen. forEach freut sich über eine Collection, also ist eine Liste eine gute Idee.

Also: Liste definieren (als konkrete Implementation des List-Interfaces steht beispielsweise die ArrayList zur Verfügung, wobei wir der “Sauberkeit” wegen der Generics bedienen, die mit Java 5 verfügbar sind), und den RequestDispatcher so definieren, daß die Anfrage am Ende von doGet(...) per forward an die definierte JSP weitergeleitet wird. Und, um beides zu verbinden, müssen wir die Liste in der JSP verfügbar machen, was wir (wie eingangs schon erwähnt) über den Request-Scope tun wollen – dorthin bekommen wir das Objekt mit request.setAttribute('name',objekt), wobei ‘name’ hier dem Namen entsprechend muß, den wir in forEach innerhalb der JSP im items-Attribut verwendet haben:

Request-Dispatcher

Soweit, so gut. Bleibt noch, die Liste mit sinnvollen Inhalten zu füllen. Dafür verwenden wir innerhalb des Servlets eine relativ simple Schleife und die Funktionen request.getAllHeaders() respektive request.getHeader(String name). (In jeder halbwegs realistischen Anwendung würde man das vermutlich so nie machen. Aber für das Beispiel ist es ein einfacher Weg, schnell exemplarische Daten zu generieren an der Stelle, an der sonst vermutlich Informationen aus der Geschäftslogik geholt werden würden…)

Header-Daten

Fehlstart und Bibliotheken

Damit haben wir zunächst erst einmal alles beisammen, um das Projekt in einem ersten Anlauf innerhalb des Servers starten zu können. Analog Teil II läßt sich das Projekt starten, das Servlet über das definierte Mapping (/view) aufrufen, und dort endet der Lauf zunächst rasch:

Fehler

Unschön, aber an sich zu erwarten: Letztlich sind die Tag-Libraries “ganz normale” Sammlungen von Java-Klassen, die natürlich der Anwendung zur Laufzeit verfügbar gemacht werden müssen, um nutzbar zu sein. Dafür gibt es in dieser Konstellation prinzipiell zwei Wege:

  • Der erste besteht darin, einfach die Taglibs (und sämtliche eventuell anderen benötigten Bibliotheken) in den entsprechenden Ordner der Tomcat-Installation (CATALINA_HOME/common/lib/) zu werfen. Bibliotheken, die dort zu finden sind, sind für alle Anwendungen innerhalb des Containers verfügbar.
  • Zweitens kann man (alternativ) auch Bibliotheken, die nur eine bestimmte Web-Anwendung benötigt, innerhalb derselben im Ordner WEB-INF/lib/ unterbringen, um sie nur für diese verfügbar zu haben.

Beide Wege haben Vor- und Nachteile, über die man sich bei Interesse in einer ruhigen Minute Gedanken machen kann. Wir wollen akut den zweiten Weg wählen, weil dieser erlaubt, die Verwaltung der zugeordneten Bibliotheken aus Eclipse heraus vorzunehmen. Konkret benötigen wir die zwei Dateien jstl.jar und standard.jar, die sich beide im Jakarta Taglibs – Paket im Unterverzeichnis lib/ befinden (so nicht eingangs bereits erledigt, ist jetzt ein guter Zeitpunkt, hierhin zu gehen und dies zu tun 😉 ).

Den Ort, an dem in Eclipse Bibliotheken zu einem Web-Projekt hinzugefügt werden sollen, findet man per Rechts-Klick auf das Proiekt, im Menü “Properties” als “J2EE Module Dependencies”:

Dependencies

Da wir um die Jar-Files, die die benötigten Bibliotheken beinhalten, wissen, können wir diese per “Add External Jars” zu den Abhängigkeiten hinzufügen…

Dependencies-2

… und die Konfiguration mit “Ok” bestätigen.

Ausgabe
Nach einem Neustart des Projektes im Tomcat-Server sollte das Ergebnis dann etwas freundlicher aussehen:
Run 2

Es zeigt sich: Der Aufruf von /view sorgt dafür, daß das Servlet die Header-Informationen aus der HTTP-Anfrage extrahiert, diese in die definierte Liste data in den Request-Scope einfügt und dann zur Ausgabe derselben view.jsp aufruft. In letzterem wird mit Hilfe der forEach-Schleife über die Elemente der Liste iteriert, um jedes einzelne mit out zur Anzeige zu bringen. Daß die Ausgabe insgesamt arg wenig ansprechend ist, sollte man der Tatsache zuschreiben, daß in view.jsp letztlich, bis auf die out-Tags, keinerlei Markup, keinerlei Formatierung zum Einsatz (wer mit dem Code spielen will, kann das gern ändern und die Effekte auf die Ausgabe beobachten…).

Fazit und Ausblick
Damit haben wir den Themenbereich der Taglibs gestreift, um zu lernen, wie man Bibliotheken in ein Java-Web – Projekt in Eclipse einführt, und wir haben betrachtet, wie man mit Servlets und JSPs eine Struktur schaffen kann, in der Java- und (X)HTML-Code weitestgehend unabhängig voneinander existieren und gepflegt werden können. Nichts davon ist erschöpfend dargelegt worden, und schon der Umfang der verfügbaren Taglibs würde ausreichen, mehrere dieser Tutorials zu schreiben. Demnächst in diesem Theater: Erzeugung eines minimalen Web-Frontends zu einem (nun ja, ebenfalls minimalen) Java-Projekt mit Geschäftlogik. Stay tuned. 😉

Lesenswertes

7 Kommentare

  1. @mschmidt: Thanks. 🙂 Kannst Dir’s in der Tat mal geben, wenn Zeit und Gelegenheit – bislang fehlt mir brauchbares Feedback zum Inhalt. 😉

  2. @Christian: Danke für den Comment / Link. 🙂 Was die JSP/JSTL-Parts in der “Insel” betrifft: Willst Du das dort wirklich ausführlicher ‘reinbringen? Ich fürchte, daß das das Buch doch insgesamt um einiges sprengen könnte…

  3. super..weiter so..ich habe alle 3 tutors ausprobiert, diese klappen ohne Probleme..vielen vielen Dank für deine Bemühung

Kommentare sind geschlossen.