Web 2.0 Software-Architekturen JSP Tag Libraries zur Generierung eigenen Markups Prof. Dr. Nikolaus Wulff Eigene Markups • Die in der JSP Definition enthalten Sprachelemente erweisen sich als unzureichend, z.B. bei der Erstellung von Schleifen oder bedingten Anweisungen. – Scriplets innerhalb einer View sind nicht gut lesbar und – schwierig zu warten. • Tag Bibliotheken gestatten es eigene, selbst definierte Markups innerhalb einer JSP zu verwenden und Scriplet Code zu eliminieren Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 2 Taglibs Seit JSP 1.1 bieten Taglibs die Möglichkeit eigene Markups zu definieren Verarbeitungslogik der View wird dorthin ausgelagert und kann so wiederverwendet werden Sie ersetzen PageBeans zur Erzeugung von HTML Tags sind besser in den Kontext der Seite eingebunden Eine Einführung bietet: http://docs.oracle.com/javaee/5/tutorial/doc/bnakc.html Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 3 Beispiel eigener Datum-Tag Einbinden eines selbst definierten Tags für eine Datumsausgabe: <%@ page language="java" %> <html> <head><title>DateTag JSP Page</title> </head> <%@ taglib uri="/NWTagLib" prefix= "lab4" %> <body> <h2>DateTag test</h2> Hier kommt die Zeit <lab4:currentDate/> und so wird sie formatiert ausgegeben <lab4:currentDate format="dd/MM/yyyy hh:mm:ss" /> Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 4 Tags Klassendiagramm PageContext (from j sp) 1 #pageContext -parent <<Interface>> Tag 0..1 TagSupport key : String / maps -value Object (from lang) doStartTag() doEndTag() JspWriter (from j sp) <<Interface>> BodyTag BodyTagSupport #bodyContent BodyContent doInitBody() doAfterBody() MyTag Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen MyTag Descriptor 5 Einbinden von Tags Erstellen einer TagKlasse, abgeleitet von Tag/BodyTagSupport. Überladen der doStart/EndTag und doInit/AfterBody Methoden. Einfügen von Setter-Methoden für Argumente im Tag Erstellen einer TagLib Descriptor Beschreibung (*.tld) für die TagKlasse(n). Bekanntgabe des TagLib Descriptors in der web.xml. optional: Deployment der Klasse(n) und Descriptoren in einem War-Archive. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 6 CurrentDateTag.java public class CurrentDateTag extends TagSupport { private SimpleDateFormat formatter; public void setFormat(String format) throws JspException { this.formatter = new SimpleDateFormat(format); } public int doStartTag() throws JspException { return TagSupport.EVAL_BODY_INCLUDE; } public int doEndTag() throws JspException { try { String currentDate; if (null != this.formatter) { currentDate = formatter.format(new Date()); } else { currentDate = new Date().toString(); } pageContext.getOut().write(currentDate); }catch(IOException e) { throw new JspException(e.toString()); } return TagSupport.EVAL_PAGE; } } Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 7 nwtaglib.tld <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <!-- offensichtlich eine sehr alte JSP Version 1.1 ... --> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>NWTagLib</shortname> <uri>NWTagLib</uri> <info> Nikos simple tag library </info> <tag> <name>currentDate</name> <tagclass>de.lab4inf.taglib.CurrentDateTag</tagclass> <bodycontent>jsp</bodycontent> <attribute> <name>format</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 8 TagLibs einbinden • Die Tag-Library Beschreibungen *.tld müssen in der web.xml nach den Servlets und ihren Mappings (DTD der web.xml!) mit ihrem symbolischen Namen bekannt gemacht werden: <web-app> <display-name>Taglib Example</display-name> <!-- custom date tag library --> <taglib> <taglib-uri>NWTaglib</taglib-uri> <taglib-location>nwtaglib.tld</taglib-location> </taglib> Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 9 JSP Standard Tag Library • Die Standard Tag Library (JSTL) definiert vier feste Bereiche {core, xml, i18n, sql} von Markups die i.A. unter den Prefix {c,x,fmt,sql} in der JSP referenziert sind. • Mit der JavaServerFaces Technologie ist als weiterer Prefix h hinzugekommen. • In der web.xml werden Taglibs bekannt gemacht, neuere JSP API Versionen kennen die JSTL bereits. • Andere Hersteller und Frameworks definieren weitere Markups und Prefix als Namensraum, die in der web.xml bekannt gemacht werden müssen... Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 10 JSTL Flavors Wichtig ist es die richtige TLD Beschreibung in der web.xml zu referenzieren, da die JSTL in zwei Varianten ausgeliefert werden. Einmal mit (JSTL1.1) einmal ohne EL (JSTL1.0). Die Tags sehen von außen identisch aus, nur die EL Ausdrücke werden intern nicht aufgelöst! In den TLDs kann dies an den unterschiedlichen Paketnamen für die Tag Klassen erkannt werden: <tag> <name>if</name> EL: <tag-class>org.apache.taglibs.standard.tag.el.core.IfTag</tag-class> RT: <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class> Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 11 Template Muster reloaded • Das JSP Site Template in einer JSTL Version: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c' %> <html> <c:import url="${HEADER}"/> <body> <div id="content"><c:import url="${CONTENT}"/></div> <div id="footer"><c:import url="${FOOTER}"/></div> </body> </html> • Header, Content und Footer sind reguläre Ausdrücke, deren Werte per c:import aus dem „request “, „session“, „application“ oder „page“ Scope ermittelt werden. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 12 JSTL prefixes Die vier JSTL Bibliotheken werden i. A. mit den vier Prefixes c, fmt, xml und sql versehen. Die URI ist laut Standard fixiert zu: http://java.sun.com/jstl/XXX XXX aus {core, format, xml, sql} Die web.xml muss einen entsprechenden Eintrag beinhalten: <!-- JSTL Tag Library Descriptor --> <taglib> <taglib-uri>http://java.sun.com/jstl/core</taglib-uri> <taglib-location>/WEB-INF/tld/c.tld</taglib-location> </taglib> Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 13 <c:set> Variablen werden mit dem set-Tag gesetzt: <c:set var="name" value="expression" scope="xxx"/> Die Variable ist danach mit dem symbolischen Namen assoziert. Die Angabe des Scope ist optional und wird per Voreinstellung auf „pageScope“ gesetzt. Der Ausdruck „expression“ kann eine einfache Variable sein oder auch ein berechneter Wert. Es werden automatisch Wrapper-Klassen verwendet. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 14 <c:out> Der einfachste Tag ist die Ausgabe: <c:out value="${book.title}" /> Die entsprechende Variable „book“ wird in folgender Reihenfolge gesucht: page Scope request Scope session Scope application Scope Diese Sichbarkeitshierarchie wird für alle JSTL Tags verwendet, es sei denn scope wird explizit angegeben. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 15 <c:out> II Es ist möglich eine Ausgabe als Voreinstellung bei <c:out> anzugeben, falls kein passendes Attribut gefunden wird. Dies geschieht mit dem default Attribute. Auch ist es möglich anzugeben ob die Ausgabe HTML konform erfolgen soll, dann werden z.B. Sonderzeichen wie „<“ als „&lt;“ dargestellt. User <c:out value="${user}" default="guest" escapeXML="true"/> Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 16 <c:if> Eine bedingte Anweisung lässt sich mit dem if-Tag realisieren: <c:if test="${!empty user}"> User <c:out value="${user}"/> logged on </c:if> Innerhalb des test Attributs kann ein EL oder auch nur eine einfache Boolsche Variable stehen. Es können normale Java Operatoren wie „==“, „!=“ oder auch symbolisch Ausdrücke wie „eq“, „ne“ vorkommen. Neu ist der Ausdruck „empty“. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 17 <c:choose/when/otherwise> Vergeblich wird ein if-else Konstrukt gesucht. Statt dessen bietet JSTL ein switch-case per choose-whenotherwise. <c:choose> <c:when test="${ count % 10 == 0 }"> <tr bgcolor="#DDDDDD"> </c:when> <c:when test="${ count % 2 == 0 }"> <tr bgcolor="#DDFFDD"> </c:when> <c:otherwise> <tr bgcolor="#DDDDEF"> </c:otherwise> </c:choose> Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 18 <c:forEach> Schleifen werden mit dem forEach-Tag realisiert. Diese Auszeichnung iteriert einheitlich über Arrays und Container und kann auch als for-Schleife verwendet werden: <c:forEach var="j" begin="1" end="4" step="1"> <tr><td><c:out value="j"/> </td> quad=<c:out value="${j*j}"/></td></tr> </c:forEach> Das Beispiel zeigt eine for-Schleife mit dem symbolischen Zähler „j“, der dann auch per EL zum Quadrieren verwendet werden kann. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 19 <c:forEach>-Iterator Auch die Iteration über eine Collection ist einfach zu realisieren: <c:forEach var="book" items="${RESULT}" > <tr><td><c:out value="${count}" /> </td> <td><c:out value="${book.title}" /> </td> <td><c:out value="${book.isbn}" /> </td> </tr> </c:forEach> Die entsprechende Collection RESULT muss vorher im page, request, session oder application Scope unter diesem Alias hinterlegt worden sein. Die Klasse Book muss als Java-Bean entsprechende getTitle, getIsbn etc. Methoden besitzen... Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 20 <c:url> Das url-Tag erlaubt den Zugriff auf andere Resourcen per Unique Ressource Locator. Darüber hinaus erleichtert es URL-rewriting, indem es eine passend assoziierte SessionId an die Variablen anfügt: <c:url var="baseurl" value="/Control" /> ... <a href='<c:out value="${baseurl}">/?task=help' alt='Help'>Help</a> Wird vom WebContainer URL-rewritting benötigt, so generiert der url-Tag dies automatisch. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 21 Empfehlungen So wenig Java-Code in JSP wie möglich. Business-Logik gehört in POJOs oder EJBs, ControllerLogik möglichst in ein Servlet oder eine PageBean. Gebrauch von JavaScript möglichst einschränken (Browser-Kompatibilitätsprobleme), diese ändert sich jedoch seit Web2.0 und entsprechende JS Frameworks. HTML sollte nicht als Rückgabewert von PageBeanFunktionen erzeugt werden, statt dessen TagLibs. Für größere Anwendungen Servlets und JSP mit MVC II Architektur einsetzen, z.B. Struts, Spring mit Tiles etc. Prof. Dr. Nikolaus Wulff Web 2.0 Software-Architekturen 22