<jsptutorial />

Java Standard Tag Library (JSTL)


Unter-Kapitel:

Motivation

Wie im Kapitel Anwendungsarchitektur schon besprochen, bieten Tag-Libraries die Möglichkeit, JSPs frei von Java-Code zu halten. Dabei übernehmen Tags Aufgaben der Darstellungslogik wie bspw. Formatierungen, Iterationen über Arrays und Listen oder ähnliche Dinge. Durch die Einführung der Tag-Libraries entstanden an vielen Stellen immer wieder die gleichen Tags (bspw. für Schleifen oder bedingte Verzweigungen). Daher lag es nahe, diese Bemühungen zu bündeln und eine einheitliche Bibliothek für die am häufigsten wiederkehrenden Aufgaben zu schaffen. Mitte 2002 wurde die JSTL, die JSP Standard Tag Library, in der ersten Version vorgelegt. Da die JSP-Version 1.2, die zum Zeitpunkt der JSTL-Version 1.0 die aktuelle Version war, noch keine Expression Language kannte, gab es die Tags in zwei Ausführungen: Mit Support für Expression Language-Ausdrücke innerhalb der Tag-Parameter und ohne diesen Support.
Erst mit der gleichzeitigen Veröffentlichung von JSTL 1.1 und der dann neuen JSP-Spezifikation 2.0, war die Expression Language vollständig in JSPs integriert - und damit entfiel die Notwendigkeit zweier JSTL-Varianten. Inzwischen ist die Version 1.2 finalisiert, entsprechend der Neuerungen mit der ebenfalls neuen JSP-Spezifikation 2.1. Die Änderungen zwischen den Spezifikationen sind am Ende dieses Kapitels im Abschnitt "Abwärtskompatibilität und Änderungen gegenüber den Vorgängerversionen" dargelegt. Im Unterschied zur Expression Language sind die Änderungen bei der JSTL nicht allzu umfangreich ausgefallen. Auf die Version 1.0 gehen wir hier nicht ein.
Die JSTL bringt - trotz ihres Namens - insgesamt fünf Tag-Libraries mit:

NameprefixURIAufgabe
corechttp://java.sun.com/jsp/jstl/core Basistags, die vor allem Programmablauf-Tags wie Schleifenkonstrukte oder Verzweigungen enthalten
fmtfmthttp://java.sun.com/jsp/jstl/fmtTags zur Formatierung von Datums-, Währungs- und Zahlwerten und zur Internationalisierung
xmlxhttp://java.sun.com/jsp/jstl/xmlGeeignet zur Bearbeitung von XML-Dokumenten. Enthält u.a. wie core Schleifen- und Verzweigungstags. Der Unterschied zu den core-Tags liegt darin, dass XPath-Ausdrücke zur Bedingungsentscheidung bzw. zur Feststellung der Menge dienen, über die iteriert werden soll
sqlsqlhttp://java.sun.com/jsp/jstl/sqlTag-Bibliothek zum Ansprechen einer Datenbank direkt aus der JSP heraus
functionsfnhttp://java.sun.com/jsp/jstl/functionsDie Tags dieser Bibliothek wenden Funktionen auf Expression Language-Ausdrücke an. Es handelt sich mit einer Ausnahme durchweg um String-Manipulationen


Eine Bibliothek aus der JSTL bindet man wie folgt in die JSP ein:

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

Im obigen Beispiel wurde die core-Bibliothek unter dem Präfix "c" eingebunden. Core-Tags können damit wie folgt genutzt werden:
<c:out value="this is simply some text" />

Hier wird der out-Tag aus der core-Bibliothek genutzt. Das "c" am Anfang des Tags entspricht dem Präfix. Dieses ist frei wählbar, doch empfiehlt es sich, die von der JSTL-Spezifikation empfohlenen Präfixe zu verwenden, die in der obigen Tabelle aufgeführt sind. Folgt man dieser Konvention, wissen alle Projektbeteiligten direkt bei einem Blick auf die JSP, welche Tag-Library jeweils verwendet wird.
Braucht man mehrere Bibliotheken muss man auch alle - wie hier gezeigt - in der JSP einbinden. Wir zeigen eine JSP, einmal klassisch mit Skriptlets und einmal mit der JSTL und der Expression Language, um zu zeigen, dass erstens Skriptlets durch die EL und die JSTL überflüssig gemacht wurden und dass zweitens dadurch eine JSP deutlich übersichtlicher wird. Außerdem kann man in diesem Beispiel die Einbindung der JSTL und deren Zusammenspiel mit der Expression Language sehen. Gerade dieses Zusammenspiel von EL und JSTL bringt beide Technologien richtig zur Geltung.
JSP mit Skriptlets:
<%@ page import="org.jsptutorial.examples.firstexample.domain.*, 
                  java.util.*" %>
<%-- ... --%>
<%
if (pageContext.findAttribute("answers") != null && ((List)pageContext.findAttribute("answers")).size() != 0) {
   List<VocabAnswer> allAnswers = (List<VocabAnswer>)pageContext.findAttribute("answers");
%>
   <table id="resultsTable" cellpadding="0" cellspacing="0" border="0">
      <tr>
         <th><fmt:message key="showResultsPage.th.orig" /></th>
         <th><fmt:message key="showResultsPage.th.translation" /></th>
         <th><fmt:message key="showResultsPage.th.answerGiven" /></th>
      </tr>
<%
   for (VocabAnswer answer: allAnswers) {
%>
      <tr class="isCorrect_<%= Boolean.toString(answer.getIsCorrect()) %>">
         <td><%= answer.getOrig().getOrig() %></td>
         <td><%= answer.getOrig().getTranslation() %></td>
         <td><%= answer.getAnswerText() %></td>
      </tr>
<%
   }
%>
   </table>
<%
}
%>

JSP mit EL und JSTL:
<c:if test="${not empty answers}">
   <table id="resultsTable" cellpadding="0" cellspacing="0" border="0">
      <tr>
         <th><fmt:message key="showResultsPage.th.orig" /></th>
         <th><fmt:message key="showResultsPage.th.translation" /></th>
         <th><fmt:message key="showResultsPage.th.answerGiven" /></th>
      </tr>
      <c:forEach items="${answers}" var="answer">
         <tr class="isCorrect_${answer.isCorrect}">
            <td>${answer.orig.orig}</td>
            <td>${answer.orig.translation}</td>
            <td>${answer.answerText}</td>
         </tr>
      </c:forEach>
   </table>
</c:if>

In den jeweiligen Unterkapiteln stellen wir die einzelnen Bibliotheken kurz vor. Dabei beschreiben wir jeweils alle Tags der jeweiligen Bibliothek und geben vereinzelt Beispiele für die Verwendung. Allerdings werden wir einige Verwendungsarten oder Attribut-Kombinationen nicht erwähnen. Dies sind durchweg Nutzungsmöglichkeiten, die in der Praxis so gut wie keine Rolle spielen. Wer wirklich alle Verwendungsarten kennen lernen möchte, sei auf die Spezifikation verwiesen.
Allgemein gilt für alle vorgestellten Tags, dass sie versuchen, soweit vernünftig möglich, mit Sonder- und Fehlerfällen umzugehen und keine Exceptions zu werfen. Dies ist daher im Einzelnen nicht gesondert erwähnt. Dennoch gibt es Fälle, bei denen eine Exception unumgänglich ist. Wir verweisen dazu auf das Kapitel Fehler- und Ausnahmenbehandlung, in dem wir zeigen, wie der Nutzerin unserer Webanwendungen unschöne Stacktraces erspart bleiben können und wir dennoch über Fehlerfälle informiert werden und zeitnah darauf reagieren können. Die dort angegebenen Regeln ersparen unseres Erachtens ein gesondertes Fehlerhandling im Umgang mit der JSTL.

Zum SeitenanfangZum Seitenanfang

Abwärtskompatibilität und Änderungen gegenüber den Vorgängerversionen

Änderungen von Version 1.0 auf Version 1.1

Wir haben eingangs des JSTL-Kapitels die URLs für die verschiedenen Bibliotheken, wie sie für die JSTL 1.1 und die JSTL 1.2 gelten, aufgeführt. In der Version 1.0 sahen die URLs anders aus. Im folgenden geben wir einen Überblick über die URLs der JSTL 1.0 und der neueren Versionen im Vergleich:

BibliothekJSTL 1.0 Expression Language-basiertJSTL 1.0 Skriptlet-basiertJSTL 1.1 und JSTL 1.2
corehttp://java.sun.com/jstl/corehttp://java.sun.com/jstl/core_rthttp://java.sun.com/jsp/jstl/core
fmthttp://java.sun.com/jstl/fmthttp://java.sun.com/jstl/fmt_rthttp://java.sun.com/jsp/jstl/fmt
sqlhttp://java.sun.com/jstl/sqlhttp://java.sun.com/jstl/sql_rthttp://java.sun.com/jsp/jstl/sql
xmlhttp://java.sun.com/jstl/xmlhttp://java.sun.com/jstl/xml_rthttp://java.sun.com/jsp/jstl/xml
functionsnicht vorhandennicht vorhandenhttp://java.sun.com/jsp/jstl/functions


Bei den URLs der Tabelle wird schon deutlich, dass die Bibliotheken der JSTL 1.0 in zwei Varianten vorlagen. Zum einen die Version, die die Nutzung von Expression Language in den Tags der JSTL erlaubte, allerdings keine RequestTime-Expressions (also <%= ... %>-Ausdrücke) innerhalb der Tag-Attribute zuließ. Diese Unterscheidung ist mit der JSTL 1.1 weggefallen.
Generell sollte man die JSTL 1.0 nur nutzen, wenn der Deployment-Deskriptor der Anwendung die Nutzung der Servlet-Spezifikation 2.3 vorsieht. Bei Nutzung der JSTL 1.0-Bibliotheken mit neueren JSP/Servlet-Spezifikationen muss auf jeder Seite die Nutzung der Expression Language explizit ausgeschaltet werden.
Mit der Version 1.1 wurde die Expression Language Bestandteil der JSP-Spezifikation und aus der JSTL-Spezifikation ausgelagert. Die Nutzung der EL ist nun innerhalb aller JSTL-Tags als auch im normalen Template-Text einer JSP möglich. Zudem wurde die functions-Bibliothek neu eingeführt, die es ermöglicht, häufig benutzte String-Manipulationen innerhalb von EL-Ausdrücken zu nutzen.
Einige Attribute, die auf "xml" begannen, wurden als deprecated markiert. Damit wurde die Konsistenz mit der XML-Spezifikation wieder hergestellt, die es nicht erlaubt, dass Attribute mit "xml" beginnen. Da JSPs auch in der Form reiner XML-Dokumente entwickelt werden können, war dies eine notwendige Änderung.

Änderungen in der JSTL seit der Version 1.2

Zwar enthält die JSTL 1.2 einige Veränderungen gegenüber der Vorgängerversion der JSTL, aber Seiten, die für die Nutzung der JSTL 1.1 geschrieben wurden, sind sofort und ohne Änderungen mit der JSTL 1.2 nutzbar. Dies ist bspw. ein Unterschied zur Expression Language, bei der sich minimale Inkompatibilitäten nicht vermeiden ließen.
Die Änderungen zwischen den Versionen JSTL 1.1 und JSTL 1.2 betreffen v.a. die Einführung der Unified Expression Language. Demnach funktionieren die Schleifentags der core-Bibliothek nun auch mit "deferred values"1 der Unified Expression Language, sofern die "items"-Attribute der Tags <c:forEach> und <c:forTokens> einen "deferred value" enthalten. Somit steht der Nutzung der JSTL innerhalb von JSF nichts mehr im Wege. Ebenso akzeptiert der <c:set>-Tag einen "deferred value" als Wert für das "value"-Attribut.

Zum SeitenanfangZum Seitenanfang

Anmerkungen:

1) Deferred Values sind Werte der Unified Expression Language, die erst im Verlauf des Lebenszyklus einer JSF-Anfrage ausgewertet werden. Außerhalb von JavaServer Faces spielen Deferred Values keine Rolle. (zurück)


www.jsptutorial.org
© 2005, 2006, 2007