Gestalten von WebPoint-Anwendungen mit Hilfe von Struts
Transcrição
Gestalten von WebPoint-Anwendungen mit Hilfe von Struts
Gestalten von WebPoint-Anwendungen mit Hilfe von Struts-Tiles Torsten Walter 1 Tutorial In dem Tutorial zu WebPoint wurde exemplarisch die Realisierung eines Videoautomaten erklärt. Dieses Dokument beschreibt darauf aufbauend, wie man eine derartige Anwendung mit Hilfe von Struts-Tiles graphisch ansprechender gestalten kann. Auch hier wird empfohlen die einzelnen Schritte gegebenenfalls per copy & paste nachzuvollziehen. Das Struts Framework ermöglicht es (Design-)Vorlagen (templates) zu erstellen, in denen Platzhalter an den Stellen stehen wo später der eigentliche Inhalt eingesetzt werden soll. Mit Hilfe einer XML-Datei wird dann beschrieben, welcher Inhalt, an statt den Platzhaltern verwendet werden soll. Das hat den Vorteil, dass man gleiche Vorlagen mehrfach verwenden und mit verschieden Inhalten füllen kann. Dadurch wird ist es später sehr leicht möglich, dass komplette Design einer Webseite anzupassen ohne viele JSP-Dateien zu ändern, indem man einfach die Vorlage verändert. 1.1 Vorarbeiten Im Laufe dieses Tutorials werden wir die bestehenden Webseiten Stück für Stück an unser neues Layout anpassen. Dazu erstellen wir uns zunächst zwei neue Ordner: • templates In diesem Ordner speichern wir später unsere templates - die Designvorlagen mit den Platzhaltern. • tiles Hier werden die tiles, der Inhalt unserer Webseite gespeichert, der später die Platzhalter ersetzen soll. Bevor wir anfangen das Layout zu definieren müssen wir zunächst unserer Videoautomaten-Projekt für Tiles konfigurieren. Dazu ergänzen wir in der Datei struts-config.xml im Verzeichnis WEB-INF die Zeilen: <plug-in className="org.apache.struts.tiles.TilesPlugin"> 2 <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" /> </plug-in> Damit teilen wir Struts mit, dass wir Tiles verwenden wollen und das wir die Vorlagen in der Datei tiles-defs.xml definieren werden. 1.2 Basislayout Nach diesem Tutorial soll der Videoautomat wie in Abbildung 1.3 aussehen. Abbildung 1.1: Das Layout für den Videoautomaten Wie man sieht besteht die Seite aus vier Teilen: Einer Kopfzeile, einer Navigationsleiste, dem eigentlichen Inhalt und einer Fußzeile. Beginnen wir also mit der Designvorlage. Dazu erstellen wir im Verzeichnis templates eine neue Datei mainLayout.jsp mit folgendem Inhalt: <%@ <%@ <%@ <%@ taglib taglib taglib taglib uri="/tags/struts-bean" prefix="bean" %> uri="/tags/struts-html" prefix="html" %> uri="/tags/struts-logic" prefix="logic" %> uri="http://struts.apache.org/tags-tiles" prefix="tiles" %> 3 <html:html> <head> <title> <bean:message key="videoautomat.caption" /> </title> </head> <body> <div id="page"> <div id="header"> <tiles:insert name="header" /> </div> <div id="menu"> <tiles:insert name="menu" /> </div> <div id="content"> <html:errors /> <tiles:insert name="content" /> </div> <div id="footer"> <tiles:insert name="footer" /> </div> </div> </body> </html:html> Im Grunde handelt es sich dabei um eine ganz normale Java-Server-Page in die wir Platzhalter in Form von <tiles:insert attribute="???" /> eingefügt haben. Der Platzhalter mit dem Namen header soll später unsere Kopfzeile enthalten, menu die Navigationsleiste, content den eigentlichen Inhalt und footer die Fußzeile. Außerdem wurden diverse div-Tags benutzt um die einzelnen Inhalte zu Gruppieren. So wird der komplette Inhalt von einem div-Tag mit der Id page eingeschlossen, die Kopfzeile durch einen div-Tag mit der Id header und so weiter. Jetzt können wir diese Designvorlage dazu benutzen neue Seiten zu erstellen, indem wir die einzelnen Platzhalter mit verschieden Inhalten füllen. Damit wir das machen können brauchen wir Dateien, in denen der Inhalt steht, der eingefügt werden soll. Für den Anfang erstellen wir dazu im Verzeichnis tiles vier Dateien: • header.jsp Mit dem Inhalt für die Kopfzeile: 4 <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <h1><bean:message key="videoautomat.caption" /></h1> • welcome-menu.jsp Mit dem Link auf die Login-Seite: <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <%@ taglib uri="/tags/struts-html" prefix="html" %> <html:link page="/LogOn.do"> <bean:message key="videoautomat.logon" /> </html:link> • welcome.jsp Mit dem Inhalt für den content-Bereich: <%@ taglib uri="/tags/webpoint" prefix="wp" %> <wp:CountingStockTable cs="<%=((videoautomat.VideoShop)web.sale.Shop.getTheShop()) .getVideoStock() %>" ted="<%=new videoautomat.TEDVideoStock()%>"/> • footer.jsp Mit dem Inhalt für die Fußzeile: A common Look and Feel using the tiles framework. Diese Dateien lassen wir jetzt für jeden Platzhalter einsetzen. Dies geschieht in der Konfigurationsdatei tiles-defs.xml. Dazu erstellen wir diese im Verzeichnis WEB-INF und füllen sie mit folgendem Inhalt: <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN" "http://struts.apache.org/dtds/tiles-config_1_3.dtd"> <tiles-definitions> <definition name=".mainLayout" path="/templates/mainLayout.jsp"> <put name="header" value="/tiles/header.jsp" /> <put name="content" value="/tiles/welcome.jsp" /> 5 <put name="footer" value="/tiles/footer.jsp" /> </definition> <definition name=".welcome" extends=".mainLayout"> <put name="menu" value="/tiles/welcome-menu.jsp" /> </definition> </tiles-definitions> Mit der Zeile <definition name=".mainLayout" path="/templates/mainLayout.jsp"> legen wir eine neue Definition“ mit dem Namen .mainLayout1 an und ver” wenden als Designvorlage die von uns erstellte Datei mainLayout.jsp. Mit <put name="???" value="/template/empty.jsp" /> wird bestimmt welche Dateien anstelle der Platzhalter eingesetzt werden sollen. Der zweite definition-Eintrag mit dem Namen welcome ist vom ist vom .mainLayout mittels extends=".mainLayout" abgeleitet. Das heißt alle Einstellungen werden von diesem übernommen, solange sie nicht lokal überschrieben werden. Jetzt müssen wir Struts nur noch mitteilen, dass wir anstelle der bisherigen Startseite unsere neue Definition verwenden soll. Dazu ändern wir einfach in der struts-config.xml die Zeile <action path="/welcome" forward="/pages/welcome.jsp" /> in <action path="/welcome" forward=".welcome" /> Nachdem wir das ganze auf den Server übertragen haben sollte die Seite wie in Abb. 1.2 aussehen. 1.3 Cascading Stylesheets Das noch recht trostlos wirkende Basislayout aus Abschnitt 1.2 wollen wir nun durch den Einsatz von Cascading Stylesheets etwas ansprechender formatieren. Dazu ergänzen wir in der Datei main-layout.jsp innerhalb des Headers, die Zeile 1 Der Name kann frei gewählt werden. In diesem Tutorial verwenden wir jedoch die Konvention, dass alle Definitionen mit dem Präfix .“ beginnen, um sie leichter von anderen forwards in der ” struts-config.xml auseinander halten zu können 6 Abbildung 1.2: Die überarbeitete Startseite. <link rel="stylesheet" type="text/css" href="<html:rewrite page=’/templates/style.css’/>" /> Damit geben wir an, dass weitere Formatierungen für diese Seite in der Datei style.css zu finden sind. Das html:rewrite sorgt dafür, dass der relative Link unter jeder beliebigen URL funktioniert, die die Vorlage benutzt. Jetzt müssen wir noch die Datei style.css im Verzeichnis templates erstellen und mit Inhalt füllen. Hier eine kommentierte Fassung der Datei: div#page { /* Hintergrundfarbe #ffffe0 setzen und zusätzlich hintergrund.gif als Hintergrundbild verwenden und in y-Richtung solange wiederholen, bis der untere Rand erreicht ist */ background: #ffffe0 url(hintergrund.gif) repeat-y; /* Rahmenfarbe setzen */ border-color: #0000CC; /* Rahmenbreite 1 Pixel */ border-width: 1px; /* Durchgezogene Linie als Rahmen verwenden */ border-style: solid; /* 1 Pixel Abstand zum Inhalt des "page"-Elements */ 7 padding: 1px; } div#header { /* minimale Höhe für den "header" von 10 Pixeln setzen */ min-height: 10px; /* Hintergrundfarbe #3399cc setzen */ background-color: #3399cc; border: 1px solid #3399cc; /* Text zentrieren */ text-align: center; } div#menu { /* das "menu" Element links ausrichten und nicht auf Seitenbreite ausdehnen */ float: left; /* Festlegen der minimale Breite des "menu"-Element auf 160 Pixel */ min-width: 160px; min-height: 100px; padding: 10px; } div#content { /* Abstand zum linken Rand auf 160 Pixel festlegen (da anfangen, wo das Menü aufhört) */ margin-left: 160px; min-height: 100px; padding: 10px; } div#footer { min-height: 10px; background-color: #3399cc; text-align: center; 8 } h1 { /* Setzt die Schriftgröße von h1 auf 16 Punkte. */ font-size: 18pt; } h2 { font-size: 16pt; } h3 { font-size: 14pt; } h4 { font-size: 12pt; } Damit wäre das Design fertig und wir könnten jetzt weitere Definitionen für die alle anderen Seiten erstellen. Diese könnten wir genau wie .welcome von unserem .mainLayout ableiten und müssten nur die Teile für das Menü und den content-Bereich anpassen. 1.4 Menü Für unsere jetzige Designvorlage muss für jede mögliche Kombination von Menüeinträgen eine neue Datei erstellt werden. In diesem Abschnitt wird gezeigt, wie man die auch die Konfiguration des Menüs mit Hilfe von Tiles erledigen kann. Im Grunde besteht das Menü nur aus einer Reihe von Links wie diesem: <html:link page="/LogOn.do"> <bean:message key="videoautomat.logon" /> </html:link> Das einzige, was sich bei den einzelnen Links ändert sind die Werte von page und key. Tiles bietet die Möglichkeit einer Definition diese Informationen mitzuteilen. Im diesem Fall würde das folgendermaßen aussehen: 9 <definition name=".welcome" extends=".mainLayout"> <putList name="items"> <item value="videoautomat.logon" link="/LogOn.do" classtype="org.apache.struts.tiles.beans.SimpleMenuItem" /> </putList> </definition> Wir übergeben der .welcome Definition eine Liste mit dem Namen items, die genau ein einziges Element vom Typ SimpleMenuItem enthält. Damit können wir das Menü innerhalb des Basislayouts (mainLayout.jsp) zum Beispiel mit folgendem Code erzeugen lassen: <div id="menu"> <tiles:importAttribute /> <logic:present name="items"> <logic:iterate id="menuItem" name="items" type="org.apache.struts.tiles.beans.MenuItem"> <html:link page="<%= menuItem.getLink()%>"> <bean:message key="<%= menuItem.getValue() %>" /> </html:link> <br> </logic:iterate> </logic:present> </div> Zur Erklärung: <tiles:importAttribute /> sorgt dafür, dass die in der tiles-defs.xml definierten Attribute der definition auf dieser Seite verfügbar sind. Der Code, der von <logic:present name="items"> und </logic:present> eingeschlossen ist wird nur dann ausgeführt, wenn ein Attribut mit dem Namen items existiert. Also nur dann, wenn wir Menüeinträge festgelegt haben. Dadurch kann die Vorlage auch dann verwendet werden, wenn das Menü leer bleibt, ohne dass man dazu eine leere Liste von itmes übergeben müsste. Der logic:iterate-Tag iteriert dann über alle items. Auf den jeweils aktuellen Menüeintrag kann man dann über die Variable menuItem zugreifen. Innerhalb der Iteration werden die Links erzeugt und die jeweiligen Werte für page und key an den entsprechenden Stellen eingesetzt. 10 1.5 Migration In diesem Abschnitt wird an Beispielen gezeigt, wie man mit der basierend auf der Vorarbeit weitere Seiten an das neue Layout anpassen kann. 1.5.1 logon.jsp Beginnen wir mit der Action logon. Dazu kopieren wir einfach die Datei logon.jsp aus dem Verzeichnis pages nach tiles und löschen aus ihr alle Teile, die nicht mehr benötigt werden, wenn die Seite innerhalb des content-Bereiches von unserem Layout angezeigt wird. Übrigrig bleibt folgendes: <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <%@ taglib uri="/tags/struts-html" prefix="html" %> <html:form action="/LogOnAction"> <table> <tr> <td align="center" colspan="2"> <h1><bean:message key="logon.caption" /></h1> </td> </tr> <tr> <td align="right"> <bean:message key="logon.enter.username" /> </td> <td align="left"> <html:text property="username" size="30" maxlength="30" /></td> </tr> <tr> <td align="right"><bean:message key="logon.enter.password" /></td> <td align="left"><html:password property="password" size="30" maxlength="30" /></td> </tr> <tr> <td align="right"><html:submit property="method"> 11 <bean:message key="videoautomat.ok" /> </html:submit></td> <td align="left"><html:cancel> <bean:message key="videoautomat.cancel" /> </html:cancel> </td> </tr> </table> </html:form> Als nächstes fügen wir der tiles-defs.xml eine neue definition hinzu <definition name=".logon" extends=".mainLayout"> <put name="content" value="/tiles/logon.jsp" /> </definition> und ändern in der tiles-config.xml das Forward der LogOn-Action zu: <action path="/LogOn" forward=".logon" /> 1.5.2 loggedin.jsp Da die Seite loggedin.jsp, mit Ausnahme der Links identisch ist mit der Startseite, ist die Anpassung an das neue Layout besonders einfach. Wir erstellen dazu eine neue Definition in der Datei tiles-defs.xml mit dem Namen .loggedin, die wir vom .mainLayout ableiten und ergänzen die Einträge für die Links. <definition name=".loggedin" extends=".mainLayout"> <putList name="items"> <item value="videoautomat.rent" link="/SelectVideos.do" classtype="org.apache.struts.tiles.beans.SimpleMenuItem" /> <item value="videoautomat.admin" link="/AdministrateAction.do" classtype="org.apache.struts.tiles.beans.SimpleMenuItem" /> <item value="videoautomat.logout" link="/LogOut.do" classtype="org.apache.struts.tiles.beans.SimpleMenuItem" /> </putList> </definition> Anschließend ändern wir noch das forward für die /loggedin-Action von /pages/loggedin.jsp auf die Definition .loggedin. 12 <action path="/loggedin" forward=".loggedin" roles="user" /> Abbildung 1.3: Die fertige loggedin-Seite 1.6 Literatur Empfehlenswerte Literatur: • http://struts.apache.org/1.3.8/index.html Die offizielle Dokumentation zu Struts 1.3.8. • http://wiki.apache.org/struts/ Auf dieser Seite findet man verschiedenste Informationen zu Struts. Sehr hilfreich sind auch die dort zu findenden Links zu weiteren Artikeln und Tutorials. • Struts in Action von Ted Husted Etwas älteres aber dennoch sehr empfehlenswertes Buch zu Struts. Auf der Seite http://www.manning.com/husted/ sind zwei Kapitel aus dem Buch zu finden. Unter anderem Kapitel 11: Developing applications with Tiles. • http://jendryschik.de/wsdev/einfuehrung/css/ Eine Einfürung in CSS. 13 • http://www.edition-w3c.de/TR/1998/REC-CSS2-19980512/ Die deutsche Übersetzung der W3C Spezifikation CSS Level 2. 14