web apps ZK, Struts und JSF

ZK vs. Struts vs. JSF – ein Erfahrungsbericht Auf welches Pferd setzen Sie?

VON DANIEL SEILER

Als Entwickler -basierender Webanwendungen steht man seit jeher vor der Entscheidung: welches Framework passt am besten zu meinen Zwecken? Soll man auf ein altbewährtes Model-View-Controllver-Framework à la Struts setzen, oder sich schon den moderneren JavaServer Faces (JSF) zuwenden? Oder möchte man gar auf der aktu- ellen Web 2.0-Welle mitreiten und ganz neue Wege gehen?

Viele Unternehmen haben in den letzten an die Entwickler in überschaubarem fache und selbstverständliche Funktionen Jahren zur Entwicklung der internen, Rahmen bleiben. HTML, JavaScript, wie sortierbare Tabellen oder das Verteilen webbasierten Geschäftsapplikationen CSS, Java, JSP und verschiedene Tag- von großen Tabellen auf mehrere Seiten, meist auf Struts-basierende Model-View- Bibliotheken gilt es zu beherrschen, um der genannt ‚Paging‘, erweisen sich häufi g als Controller-Frameworks gesetzt. Das so Aufgabe, eine ansprechende Benutzerober- zeitaufwändige Probleme, die jedes Mal zum defacto Standard avancierte Struts fl äche zu entwickeln, gewachsen zu sein. von Neuem gelöst werden müssen. gewährleistet dabei eine konsistente Ar- Der Anspruch der Benutzer auf Inter- So steht mit den Java Server Faces (JSF) chitektur und sorgt für ein akzeptables aktivität und ein professionelles Erschei- seit 2004 ein Standard zur Verfügung, der Maß an Wartbarkeit. Dieser Ansatz funk- nungsbild geht dabei meist zulasten der die Web-Entwicklung unter Jav a auf ein tioniert soweit ganz gut, wenn auch die Wartbarkeit der JSP-Seiten und auch die nächst höheres Level heben soll und die Komplexität der Benutzeroberfl äche und Produktivität in der Entwicklung lässt mittlerweile bekannten Schwachpunkte die damit verbundenen Anforderungen häufi g zu wünschen übrig. Scheinbar ein- von Struts ausmerzen. Und gerade im

www.javamagazin.de 10.2007 85 web apps ZK, Struts und JSF

können, habe ich mir folgende Rahmen- bedingungen auferlegt:

1. Es soll jeweils dieselbe Architektur ver- wendet werden. 2. Code, welcher nicht zur Präsentations- schicht gehört, soll von allen drei Fra- meworks gemeinsam genutzt werden. 3. Es soll keine Zeit in das Verschönern der Benutzeroberfläche investiert werden. 4. Es soll für die Implementierung bei je- Abb. 1: Architektur der Beispielapplikation dem Framework in etwa gleichviel Zeit investiert werden. &VSPQBTHSz‡UF4FDPOE-JGF,POGFSFO[ Kontext des aktuellen Web 2.0-Hypes ist und ZK. Es ist auch kein Tutorial, wie die Diskussion um das beste und wahre man Applikationen mit Struts, JSF oder Architektur VOE/PWFNCFS'PSVNBN%FVUTDIFO.VTFVN .ODIFO Framework zur Entwicklung von Java ZK entwickelt. Das Ziel dieses Artikels In der Praxis hat sich der Model-View- Web-Applikationen neu entbrannt. Das ist es, anhand einer einfachen, aber aussa- Controller (MVC)-Ansatz bewährt und Ziel dabei ist, die Entwicklung solcher gekräftigen Beispielapplikation, Stärken, soll daher als Architektur für alle drei Applikationen weiter zu vereinfachen Schwächen und Potenzial der ausgewähl- Frameworks zum Einsatz kommen. Da- und das Benutzererlebnis zu steigern. ten Frameworks zu beleuchten. bei beschreibt das Modell die Geschäfts- Als Entwickler oder Technologieve- objekte und die Geschäftslogik, die View rantwortlicher von webbasierten Java- Funktionalität der Beispielapplikation präsentiert dem Benutzer das Formular Anwendungen steht man also vor der Wie oben erwähnt, soll die Beispielappli- und die Daten, während der Kontroller schwierigen Entscheidung, auf welches kation die wichtigsten Elemente einer sich um die korrekte Verarbeitung der Be- Framework-Pferd man im nächsten ausgewachsenen Geschäftsapplikation nutzereingaben kümmert (Abb. 1). Projekt setzen soll. Welche Webtechno- enthalten. In der Praxis hat sich gezeigt, Die Daten, die der Benutzer in die For- logien werden sich in Zukunft durchset- dass sehr oft die Hauptaufgabe solcher mularmaske eingibt, werden an den Con- zen? Sind es die Java Server Faces, JBoss Applikationen darin besteht, Daten in troller geschickt. Dieser extrahiert und va- Seam, , Laszlo, Dojo, DWR, Google strukturierter Form zu erfassen, abzu- lidiert die Formulardaten und aktualisiert Web Toolkit, ICEFaces, Ajax4JSF, Spring speichern und wieder darzustellen. Dies das Modell der Applikation. In unserem MVC, Struts, ZK etc. oder eine Kombina- ist daher genau die Funktionalität, die un- Fall besteht das Modell, das von allen drei tion aus den verschiedenen Ansätzen? ser Beispiel abdecken sollte. Frameworks gemeinsam genutzt wird, Um dieser Frage nachzugehen, habe Dem Benutzer wird ein Formular ange- aus einem einfachen Personen-Objekt ich beschlossen, eine möglichst einfache zeigt, auf dem er Personendaten wie Vorna- (Listing 1). Beispielapplikation, die dennoch die me, Nachname etc. eingeben kann. Sobald wichtigsten Elemente einer ausgewach- er auf Submit drückt, werden die Daten an Struts #FJBONFMEVOH senen Geschäftsapplikation enthält, mit den Server übermittelt und an ein ‚Data Struts ist das ‚Urgestein‘ der drei Fra- CJT[VN4FQUFNCFS drei verschiedenen Frameworks – ZK, Access Object‘ (DAO) übergeben, welches meworks. Die Grundidee von Struts ist LzOOFOTJF Struts und JSF – zu entwickeln. das Speichern der Daten in eine Datenbank einfach: Ein zentrales Action-Servlet  Verschiedene Gründe haben zu dieser simuliert. Als Resultat wird dem Benutzer empfängt die Http-Requests des Benut- TQBSFO Wahl beigetragen: So ist ZK konsequent die aktuelle Liste der gespeicherten Per- zers, füllt, falls gewünscht, automatisch komponentenorientiert und beinhaltet sonen in Form einer Tabelle angezeigt. die Formulardaten in ein entsprechendes eine große Anzahl von Standardkom- Was zeigt uns dieses Beispiel? Zum Action-Form Objekt ab und leitet die ponenten. ZK verfügt über eine über- einen werden verschiedene Standard- Anfrage an ein spezifisches Struts- durchschnittlich umfangreiche Doku- Formularkomponenten benutzt, wie z.B. Action-Objekt weiter. Dieses Action- mentation, ist Open Source und wird Textfeld, Datumsfeld, Checkbox, Select- Objekt erfüllt die Rolle des Controllers, #64*/&44 5&$)/*, $0..6/*5: auf Sourceforge aktiv weiterentwickelt. box und Radiobuttons. Zum anderen indem es die im Form-Objekt gespei- 53"$, 53"$, 53"$, Ebenfalls für ZK spricht das durchdachte, wird das Übermitteln und wieder Anzei- cherten Daten in das entsprechende serverseitige Modell und die Tatsache, gen der Formulardaten sowie das Aufbau- Personen-Objekt abfüllt, die Liste mit 'S1SPHSBNNJFSFS (FTUBMUFSVOE$POUFOU dass die zur Darstellung verwendeten en und Aktualisieren einer Tabelle mit den allen Personen-Objekten aktualisiert 'S.BSLFUJOH&OUTDIFJEFS EJFFJO &OHBHFNFOUJO4FDPOE-JGFQMBOFO $SFBUFS-FSOFO4JFEJFHFTBNUF1BMFUUFEFS %BT'PSVNGSBMMFOJDIULPNNFS[JFMMFO ZUL-Seiten auf dem XML User Interface Resultaten demonstriert. und anschließend die JSP aufruft, die zur PEFSBVTCBVFOXPMMFO *OHBNF(FTUBMUVOHTNzHMJDILFJUFOLFOOFO 4FDPOE-JGF/VU[FS Language (XUL) Standard basieren. Darstellung des Formulars und der Liste Der folgende Artikel erhebt nicht den Rahmenbedingungen mit den Personendaten bestimmt ist. Die Anspruch einer kompletten Analyse der Um die verschiedenen Frameworks auch Entwicklung der Beispielapplikation mit drei Frameworks Struts, Apache MyFaces möglichst aussagekräftig vergleichen zu Struts ist schnell und einfach zu realisie- XXXNFUBWFSTFDPN

7FSBOTUBMUFS *OJUJBUPS .FEJB1BSUOFS 86 10.2007 www.javamagazin.de "ONFMEFGPSNVMBS web apps ZK, Struts und JSF $POGFSFODF4QFDJBMT  &BSMZ#JSECFJ"ONFMEVOHCJT[VN4FQUFNCFS ren. Es werden dabei folgende Kompo- falls noch erstellt werden muss, ist die in ein PersonBean-Objekt kopieren. Dies  4QFDJBM1SFJTFGSEJF$PNNVOJUZ nenten entwickelt: struts-config.xml-Datei, welche die De- geschieht mithilfe der Jakarta Commons Der Controller, vertreten durch die finitionen der Struts-Actions, der Struts- BeanUtils Bibliothek durch folgenden Auf- SimpleAction-Java-Klasse (Listing 2), die Forms sowie die Navigationsregeln ent- ruf: SimpleForm-Klasse, die hier nicht abgebil- hält. ,POGFSFO[ &BSMZ#JSE 4UBOEBSE (MFJDIQFS'"9BO det ist, da sie nur alle Felder des Formulars Man beachte, dass die Formularda- BeanUtils.copyProperties(personBean,form);  °  ° und die dazugehörigen Getter- und Set- ten automatisch von Struts in die Simple­   #VTJOFTT  .P °%J     ter-Methoden enthält sowie die JSP-Seite Action-Form abgefüllt werden. Man Das gefüllte PersonBean-Objekt wird   5FDIOJL  .P °%J   °  ° simple.jsp als View (Listing 3). Was eben- muss jetzt allerdings noch die Formdaten dann an das Data Access-Objekt überge-

  #VTJOFTT  .P   °  ° 1FS1PTUBO Listing 1 4PGUXBSF4VQQPSU   #VTJOFTT  %J   °  ° 7FSMBH(NC) PersonBean.java 5FDIOJL  .P   °  ° Ã.FUBWFSTF²   package com.ebpm.webdemo.common; return birthdate; this.married = married; (FMFJUTTUSB‡F } } 5FDIOJL  %J   °  °   'SBOLGVSUBN.BJO import java.util.Date; public void setBirthdate(Date birthdate) { public float getWeight() { this.birthdate = birthdate; return weight; 0IOF .JU public class PersonBean { } } $PNNVOJUZ 7FSQGMFHVOH 7FSQGMFHVOH 0EFSPOMJOF private String firstname; public String getFirstname() { public void setWeight(float weight) {  °  °    5FJMOBINFBN.POUBH  XXXNFUBWFSTFDPN private String lastname; return firstname; this.weight = weight; private String address; } }  °  °    5FJMOBINFBN%JFOTUBH  private String color; public void setFirstname(String firstname) { public String getColor() {

"MMF1SFJTF[[HM.X4U private Date birthdate; this.firstname = firstname; return color;  5FJMOBINFBO#VTJOFTT° 5FDIOJL°VOE$PNNVOJUZ5SBDLT 'SBHFO private float weight; } }  5FJMOBINFBO5FDIOJL°VOE$PNNVOJUZ5SBDLT #JUUFTFOEFO4JFFJOF&.BJMBO private boolean married; public String getLastname() { public void setColor(String color) { 5FJMOBINFOVSBO$PNNVOJUZ5SBDLT 7PVDIFSGSXBIMXFJTF private String rating; return lastname; this.color = color;  FJOFO#VTJOFTT°PEFSFJOFO5FDIOJL7PSUSBH TLJSDIOFS!NFUBWFSTFDPN } } PEFSSVGFO4JFVOTBO public String getAddress() { public void setLastname(String lastname) { public String getRating() { $PNNVOJUZ$PEF    return address; this.lastname = lastname; return rating; } } } public void setAddress(String address) { public boolean isMarried() { public void setRating(String rating) { this.address = address; return married; this.rating = rating; 5FJMOBINFCFEJOHVOHFO } } } 3FDIOVOHTBOTDISJGU CJUUFVOCFEJOHUWPMMTUjOEJHBOHFCFO   %FS5FJMOBINFCFJUSBHGSEJF.FUBWFSTF public Date getBirthdate() { public void setMarried(boolean married) { } CFJOIBMUFUEJFBVGEFS.FUBWFSTF8FCTJUF /BNF 7PSOBNF 5FJMOFINFS BOHFHFCFOFO-FJTUVOHFO#FJ"ONFMEVOHFOCJT [VN4FQUFNCFSHJMUEFSBOHFHFCFOF 'JSNB 'SICVDIFSQSFJT#FJ"ONFMEVOHOBDIEJFTFN Listing 2 5FSNJOHJMUEFSBOHFHFCFOF4UBOEBSEQSFJT 4USB‡F "MMF1SFJTFWFSTUFIFOTJDI[[HMEFSHFTFU[ SimpleAction.java MJDIFO.FISXFSUTUFVFS%JFTHJMUBVDIGS package com.ebpm.webdemo.struts; HttpServletResponse response) PersonBean personBean = new PersonBean(); 1-; 0SU 5FJMOFINFSBVTEFN"VTMBOEVOEEFS&6 „ B 6TU( %FS5FJMOBINFCFJUSBHJTUGjMMJHOBDI throws Exception BeanUtils.copyProperties(personBean,form); 5FMFGPO 5FMFGBY 3FDIOVOHTTUFMMVOH%JF5FJMOBINFJTUOVSNzH import java.util.Collection; { // pass the data to the persistency layer MJDI XFOOEFSWPMMTUjOEJHF3FDIOVOHTCFUSBH PersonDAO.getInstance().addPerson(personBean); &.BJM 5FJMOFINFS WPS#FHJOOEFS7FSBOTUBMUVOHCFHMJDIFOJTU import javax.servlet.http.HttpServletRequest; String subaction = request.getParameter(“subaction“); } else { "ONFMEVOHFOLzOOFOCJT[VN4FQUFNCFS import javax.servlet.http.HttpServletResponse; // If user pressed ‘Cancel’ button, return to home page this.addErrors(request, errors); ;BIMVOHTXFJTF TUPSOJFSUXFSEFO'SEJF4UPSOJFSVOHTUFMMU if (isCancelled(request)) { }   QFS#BOLFJO[VH EFS7FSBOTUBMUFS [[HM.X4UJO3FDIOVOH import org.apache.commons.beanutils.BeanUtils; return mapping.findForward(“home“); } /BDIEJFTFN;FJUQVOLUJTUFJOF4UPSOJFSVOHOJDIU import org.apache.struts.action.*; } // get all the PersonBeans from the persistence layer NFISNzHMJDIVOEEFSWPMMF3FDIOVOHTCFUSBH #BOL import com.ebpm.webdemo.common.*; Collection personBeans = PersonDAO.getInstance(). JTU[VCFHMFJDIFO%FS7FSBOTUBMUFSCFIjMUTJDI if(subaction != null && “addperson“. getAllPersons(); ,POUP/S    #-; EBT3FDIUWPS BVTBLUVFMMFN"OMBTTCFEJOHUF `OEFSVOHFOBN1SPHSBNNWPS[VOFINFO public class SimpleAction extends Action { equals(subaction)) { request.setAttribute(“personBeans“, personBeans);  QFS,SFEJULBSUF #FJ"CTBHFEFS7FSBOTUBMUVOHEVSDIEFO // validate the data // forward to the result page 7FSBOTUBMUFSXFSEFOCFSFJUTHF[BIMUF public ActionForward execute( ActionErrors errors = validate return mapping.findForward(“success“);  7*4"  &630."45&3$"3% 5FJMOBINFCFJUSjHF[VSDLFSTUBUUFU8FJUFSF ActionMapping mapping, ((SimpleActionForm)form); } "OTQSDIFHFHFOCFSEFN7FSBOTUBMUFSCFTUF ActionForm form, if(errors.size() == 0) { ,BSUFO/S     HMUJHCJT IFOOJDIU8JSEEJF7FSBOTUBMUVOHWFSTDIPCFO  HttpServletRequest request, // copy the form data into the person bean } CFIBMUFOEJF"ONFMEVOHFOJISF(MUJHLFJU ,BSUFOJOIBCFS $7$/S   1SPEVLUVOE.BSLFOOBNFOTJOEJOEFS3FHFM   FJOHFUSBHFOF8BSFO[FJDIFOEFSFOUTQSFDIFOEFO  OBDI&SIBMUEFS3FDIOVOH 6OUFSOFINFO %JF.FUBWFSTFJTUFJOF7FSBOTUBMUVOHEFT 4PGUXBSF4VQQPSU7FSMBH%BT$PQZSJHIUGSBMMF *OIBMUFEFS,POGFSFO[MJFHUCFJN7FSBOTUBMUFS www.javamagazin.de 10.2007 0SU %BUVN SFDIUTWFSCJOEMJDIF6OUFSTDISJGUVOE'JSNFOTUFNQFM 91 web apps ZK, Struts und JSF

Abb. 2: Struts- an die simple.jsp-View zur Darstellung Resultat des Resultats. Auf dem Bildschirm sieht die Ausgabe dann wie in Abbildung 2 aus. Gemäß den definierten Rahmenbedingungen wird keine Zeit ins Design investiert, dement- sprechend ist auch das Resultat optisch wenig ansprechend. Meine Beobach- tungen beim Entwickeln dieser Beispiel­ applikation mit Struts lassen sich wie folgt zusammenfassen: Einerseits ist Struts sta- bil, schnell und nach dem Überwinden der üblichen Konfigurationshürden,i ntuitiv zu benutzen und ausgereift. Es erlaubt eine saubere Trennung von Darstellung, Kontrollfluss und Geschäftslogik, wobei allerdings auch einiges an Disziplin auf der Entwicklerseite gefordert ist, um di- ese Trennung wirklich konsequent einzu- ben, welches je nach Implementierung die Personendaten abgefragt und im Http­ halten. Es ist grundsätzlich auch möglich, Personendaten in einem Datenspeicher Request unter dem Namen personBeans die JSP mit Geschäftslogik ‚anzureichern‘ ablegt. Wieder über das Data Access- abgelegt. Der Controller hat nun seine Ar- oder die gesamte Geschäftslogik im Con- Objekt werden dann alle gespeicherten beit erledigt und leitet die Anfrage weiter troller zu verpacken.

Listing 3

simple.jsp

Green Blue value=“addperson“/> * Lastname:

... Are you maxlength=“50“/> married?

How much do you like yourself?:

/>

FirstnameLastnameAddress th> maxlength=“50“/> value=“1“> Actually, I hate me. much. maxlength=“80“/> indifferent. pretty neat. totally in love with me. format=“dd.MM.yyyy“ />
Weight * Firstname:
BirthdateColorMarriedRating
Not so Address:
I’m ${personBean.lastname} ${personBean.firstname}
I’m ${personBean.address}
${personBean.weight} Weight: I’m
Birthdate:
${personBean.color} ${personBean.married} ${personBean.rating}

What is your favorite color?: Red

...

92 10.2007 www.javamagazin.de web apps ZK, Struts und JSF

Andererseits handelt es sich bei der Abb. 3: JSF-Resultat JSP-Programmierung immer noch um harte Knochenarbeit. Trotz vielen Be- mühungen der Struts- Community wird es ohne fundierte HTML-, Java-, Java­ Script- und Tag-Library-Kenntnisse schwierig, eine ansprechende Seite zu gestalten. Es gibt auch wenig (bis keine) Standardkomponenten wie z.B. einen Ka- lender, den ich mir in dieser Anwendung gewünscht hätte. Mit der neuen Expres- sion Language, die in die Version 2.0 der JSP-Spezifikation Einzug gefunden hat, lassen sich die JSPs zwar relativ kompakt und übersichtlich darstellen – nur wenn die Daten formatiert ausgegeben werden sollen, muss noch auf das ‚alte‘ -Tag zurückgegriffen werden. In unserem Beispiel wird dies am Datums- Feld birthdate demonstriert. Das Kopie- die JSPs durch eine auf Templates basie- der Managed Beans und deren Methoden ren der Form-Daten ins Personen-Objekt rende Technologie zu ersetzen. In unserem erlaubt, sehr gute Dienste. Was ebenfalls hinterlässt einen etwas seltsamen Nach- Beispiel wird die JSP-Seite simple.jsp zur auffällt, sind die JSF- Standardkompo- geschmack, obwohl mit der Jakarta Com- Darstellung benutzt. nenten, wie z.B. die Tabellen-Komponen- mons BeanUtils Bibliothek diese Aufgabe Was beim Managed Bean auffällt, te . Das manuelle Iterieren größtenteils automatisiert werden kann. ist das Fehlen eines Form-Objektes, wie über eine Liste von Elementen wie bei wir es bei Struts gesehen haben. Die View Struts entfällt, dafür wird die Liste, wel- JSF (MyFaces) greift über die Methode getPersonBean() che als Tabelle angezeigt werden soll, über Kommen wir nun zu JSF, seit Mai 2006 in direkt auf das PersonBean zu und bindet das Managed Bean referenziert und die der Version 1.2 verfügbar. Im Gegensatz die Attribute dieser Beans an die entspre- benötigten Kolonnen definiert. Die Aus- zu Struts handelt sich hier um einen ‚rich- chenden Komponenten der View. Aus gabe auf dem Bildschirm sieht dann aber, tigen‘ Standard, der vom Java Community diesem Grund braucht man kein Form- wie in Abbildung 3 zu sehen ist, sehr ähn- Process autorisiert ist. Was dies für die Objekt als Vermittler zwischen View und lich der mit Struts erstellten Applikation Entwicklung von Applikationen bedeu- Controller (Listing 5). aus (Abb. 3). tet, werden wir in diesem Abschnitt noch Auch hier verrichtet die Expression JSF bietet standardmäßig einige Un- sehen. Das Ziel der JSF-Spezifikation ist Language, welche ein direktes Ansprechen terstützung, um mithilfe eines so genann- es, die Webentwicklung, mehr als dies bei Struts der Fall ist, zu vereinfachen und Listing 4 dank einem durchdachten Komponen- tenmodell von der JSP-Programmierung SimpleManagedBean.java so weit wie möglich zu abstrahieren. package com.ebpm.webdemo.jsf; { Was bei Struts die Action-Klassen PersonDAO.getInstance().addPerson(personBean); sind, sind bei JSF die Managed Beans. import java.util.Collection; } Die Managed Beans werden in der Datei import javax.faces.application.FacesMessage; return “success”; faces-config.xml definiert und können, import javax.faces.context.FacesContext; } anders als bei Struts die Actions, direkt import com.ebpm.webdemo.common.*; aus der View über eine Expression Langu- public String cancel() { age angesprochen werden. Das Managed public class SimpleManagedBean { return “home”; Bean SimpleManagedBean übernimmt in private PersonBean personBean = new PersonBean(); } unserem Beispiel die Rolle des Controllers (Listing 4). Als View kommen auch bei den public PersonBean getPersonBean() { public Collection getAllPersons() { return personBean; return PersonDAO.getInstance().getAllPersons(); JSF standardmäßig JSPs zum Einsatz (Lis- } } ting 5). Gemäß dem JSF-Standard wird die Technologie bei der View nicht vorge- public String addPerson() { ... schrieben. Das Facelets Projekt [8] liefert if(validate(FacesContext.getCurrentInstance())) } hier einige sehr interessante Ansätze, um

www.javamagazin.de 10.2007 93 web apps ZK, Struts und JSF ten Converters das Geburtsdatum in ein ponenten noch nicht soweit ausgereift, von Nöten sind und man kommt auch um Datum-Objekt umzuwandeln und bei wie sie sein könnten und das Suchen und den Eindruck nicht herum, dass sich be- der Anzeige wieder entsprechend zu for- Integrieren der passenden Komponente züglich der Komplexität der Seite gegenü- matieren. Das durchdachte Komponen- aus den vielen verschiedenen Komponen- ber Struts nicht allzu viel verbessert hat. tenmodell sowie das direkte Aufrufen der ten-Bibliotheken gestaltet sich als zeitrau- Managed Beans über die Expression Lan- bendes Unterfangen. Schaut man sich die ZK guage bieten einige Vorteile gegenüber JSP der JSF-View an, so sieht man, dass Nach Struts und JSF schauen wir in die- Struts. Leider sind die verfügbaren Kom- immer noch einige HTML-Kenntnisse sem Kapitel als letztes Framework einen

Listing 5

simple.jsf

What is your favorite color?: ... {SimpleManagedBean.personBean.color}”>

Simple JSF Demo

How much do you like yourself?:

{SimpleManagedBean.personBean.rating}” > indifferent” /> neat” />

{SimpleManagedBean.cancel}” value=”Cancel” />

...
* Lastname: {SimpleManagedBean.personBean.lastname}” /> Are you married?

size=“40“/>
* Firstname: {SimpleManagedBean.personBean.firstname}” size=“40“/>
Address: {SimpleManagedBean.personBean.address}” love with me” /> size=“80“/>
Weight: {SimpleManagedBean.personBean.weight}” size=“5“/>
Birthdate: {SimpleManagedBean.personBean.birthdate}” size=“20“> ”dd.MM.yyyy”/>

94 10.2007 www.javamagazin.de web apps ZK, Struts und JSF

Vertreter der neuen Web-2.0-Generation und einer im Browser sichtbaren Darstel- Tag auf dem Server durch die Klasse org. an. ZK ist ein Open-Source-Projekt und lung. Die Komponenten können dabei zkoss.zul.Window implementiert. Um wurde 2004 ins Leben gerufen. Es steht entweder in einer XUL-basierten XML- nun unsere MVC-Architektur in ZK ab- unter der GPL-Lizenz, bietet aber, analog Sprache, in so genannten ZUL-Seiten, zubilden, besteht die Möglichkeit, durch zu MySQL, ein Dual Licensing- Modell beschrieben oder aber komplett in Java das XML Attribut use des window-Tags an, sodass ZK auch für kommerzielle programmiert werden. Welche Variante eine eigene Version der org.zkoss.zul. Applikationen, die nicht unter die GPL im konkreten Fall gewählt wird, XML Window-Klasse zu definieren. In unserem gestellt werden sollen, eingesetzt wer- oder Java, ist zum Teil eine Geschmacks- Beispiel ist es die SimpleWindow-Klasse den kann. Gemäß Wikipedia ist ZK ein frage, aber auch Gegenstand von Er- in Listing 6, welche die Rolle des Control- -basiertes Webapplikation-Fra- fahrung und Architekturüberlegungen. lers übernimmt. Die Komponenten einer mework, das eine interaktive Benutzer­ Dem Autor hat es auf jeden Fall viel Spaß ZUL-Seite können über das jeweilige id- oberfläche ermöglicht und dies alles ohne gemacht, nach den vielen JSPs die Benut- Attribut referenziert werden. So bewirkt JavaScript zu programmieren. ZK wird zeroberfläche, ähnlich wie bei , in ein Klicken auf den Submit-Button, dass von der Firma Potix Corporation aktiv Java zu programmieren. die Methode addPerson() der SimpleWin- unterstützt und weiterentwickelt. Es ist Die Hauptkomponente einer ZK- dow-Klasse aufgerufen wird. strikt komponentenbasiert, .h. alles was ZUL-Seite ist die Window-Komponen- Wie bei den meisten ZK-Requests im Browserfenster angezeigt wird, sind te. Auf der Seite wird diese Komponente handelt es sich auch bei dem Aufruf der Komponenten. Dabei besteht jede Kom- durch das -Tag beschrieben. addPerson()-Methode um einen Ajax- ponente aus einem serverseitigen Modell Standardmäßig wird das - Request. Dieser wird asynchron durch

Listing 6

SimpleWindow.java

package com.ebpm.webdemo.; (“/simpleWindow/weight”); (personBean.getFirstname())); Datebox birthdate = (Datebox)Path.getComponent row.getChildren().add(new Label import java.text.SimpleDateFormat; (“/simpleWindow/birthdate”); (personBean.getLastname())); import java.util.*; Combobox color = (Combobox)Path.getComponent row.getChildren().add(new Label (“/simpleWindow/color”); (personBean.getAddress())); import org.zkoss.zk.ui.Component; Checkbox married = (Checkbox)Path.getComponent row.getChildren().add(new Label(Float.toString import org.zkoss.zk.ui.event.Event; (“/simpleWindow/married”); (personBean.getWeight()))); import org.zkoss.zk.ui.event.EventListener; Radiogroup rating = (Radiogroup)Path.getComponent row.getChildren().add(new Label(sdf.format import org.zkoss.zul.*; (“/simpleWindow/rating”); (personBean.getBirthdate()))); row.getChildren().add(new Label import com.ebpm.webdemo.common.PersonBean; PersonBean personBean = new PersonBean(); (personBean.getColor())); import com.ebpm.webdemo.common.PersonDAO; personBean.setFirstname(firstName.getValue()); Checkbox cb = new Checkbox(); personBean.setLastname(lastName.getValue()); cb.setChecked(personBean.isMarried()); public class SimpleWindow extends Window personBean.setAddress(address.getValue()); cb.setDisabled(true); { personBean.setWeight(new Float(weight.getValue()). row.getChildren().add(cb); public static SimpleDateFormat sdf = new floatValue()); row.getChildren().add(new Label SimpleDateFormat(“dd.MM.yyyy”); personBean.setBirthdate(birthdate.getValue()); (personBean.getRating())); personBean.setColor(color.getValue()); } public void onCreate() personBean.setMarried(married.isChecked()); { personBean.setRating(rating.getSelectedItem(). private void createPersonsGrid() createPersonsGrid(); getValue()); { } PersonDAO.getInstance().addPerson(personBean); Grid personsGrid = Path.getComponent(“/simpleWindow/ Grid personsGrid = Path.getComponent personsGrid”); public void addPerson() (“/simpleWindow/personsGrid”); // add all the personsBeans { Rows rows = personsGrid.getRows(); Collection personBeans = PersonDAO.getInstance(). // extracting the person data addRow(personBean,rows,rows.getChildren().size()); getAllPersons(); Textbox firstName = (Textbox)Path.getComponent } for(Iterator it = personBeans.iterator(); it.hasNext();) (“/simpleWindow/firstname”); { Textbox lastName = (Textbox)Path.getComponent private void addRow(PersonBean personBean, Rows rows) PersonBean personBean = (PersonBean)it.next(); (“/simpleWindow/lastname”); { addRow(personBean,rows); Textbox address = (Textbox)Path.getComponent Row row = new Row(); } (“/simpleWindow/address”); rows.appendChild(row); } Textbox weight = (Textbox)Path.getComponent row.getChildren().add(new Label }

www.javamagazin.de 10.2007 95 web apps ZK, Struts und JSF

Klasse SimpleWindow kein reiner Con- troller mehr, da sie auch GUI-spezifische Funktionalität enthält. Ob dies nun gut oder schlecht ist, kann natürlich dis- kutiert werden. ZK würde es auf jeden Fall auch erlauben, die Applikation an- ders zu strukturieren und das Aufbauen der Personentabelle auf der ZUL-Seite durchzuführen. Das sauberste Design für diese Applikation wäre gewesen, die Personentabelle als eigenständige ZK- Komponente zu implementieren: Einer der mächtigsten Eigenschaften von ZK Abb. 4: ZK Resultat ist nämlich die Möglichkeit, auf einfache Weise eigene Komponenten zu definie- einen JavaScript-Aufruf vom Client an angezeigt - eine schöne interaktive Ajax- ren, die dann über ein entsprechendes den Server gesendet. Als Antwort auf Anwendung eben. In der addRow()-Me- XML-Tag in die ZUL-Seiten eingebun- diesen Request wird nicht mehr die gan- thode sieht man auch, wie eine grafische den werden können. Was bei ZK auch ze ZUL-Seite zurückgegeben (Listing 7) Komponente auf der Serverseite in Java überzeugt hat, sind die verfügbaren und erneut aufgebaut, sondern es wird in aufgebaut wird. Standardkomponenten: Ob Kalender, der addRow()-Methode lediglich der Teil Was in diesem Beispiel mit ZK auf- Comboboxen oder sortierbare Tabellen, der Darstellung aktualisiert, der durch fällt, ist die aufgeräumte und übersicht- ZK lässt diesbezüglich fast keine Wün- den Aufruf betroffen ist. D.h. es wird nur liche ZUL-Seite. Die Seite enthält keiner- sche offen, wie das Resultat in Abbildung eine zusätzliche Zeile in der Personenta- lei Programmierlogik, wie zum Beispiel 4 zeigt. belle eingefügt. Da nicht die ganze Seite das Iterieren über eine Liste, sondern Natürlich ist auch bei ZK nicht alles neu aufgebaut werden muss, wird das beschreibt lediglich die darzustellenden Gold, was glänzt. So entpuppte sich das Resultat entsprechend schnell wieder Komponenten. Dafür ist die Controller- Extrahieren der Formulardaten über die

Listing 7

simple.zul

means Red ;-)”/> zk.SimpleWindow” title=”Simple ZK Demo”