AJAX-Webportal mit Google Web Toolkit und Tapestry Entwickelt von Daniel Tahin 0226781 und Oliver Grof 0227374 Betreut von Univ. Ass. Dipl.-Ing. Dr. Hilda Tellioglu Technische Universität Wien Institut für Gestaltungs- und Wirkungsforschung Multidisciplinary Design Group 1. Einführung In diesem Dokument wird das Ergebnis der Projektarbeit von Daniel Tahin (TU Wien, Matrikelnummer:0226781) und Oliver Grof (TU Wien, Matrikelnummer:0227374) beschrieben. Die Aufgabe bestand darin, im Rahmen des vierstündigen Projektpraktikums ein AJAX-Webportal zu entwickeln, mit dem es möglich ist Datenbanksuchen und – Manipulationen durchzuführen. Das Wort AJAX steht in der Programmierung für Asynchronous Javascript and XML, einem relativ neuen Paradigma, bei dem es meistens darum geht mit verschiedenen bekannten Technologien eine interaktive, Desktop-ähnliche Webanwendung zu realisieren. Wichtig hierbei ist, das man eine HTTP-Anfrage durchführen kann (und soll), ohne die ganze Seite neu laden zu müssen. Es gibt natürlich mehrere Ansätze, die auf dieser asynchronen Kommunikation basieren; wir haben uns für zwei, sehr leistungsfähige Vertreter, Tapestry und Google Webtoolkit entschieden. Genaue Beschreibung zu diesen und den anderen verwendeten Technologien finden sie natürlich auch alles in dieser Dokumentation. Außerdem werden die fertigen Komponenten, Features beschrieben, Probleme, Weiterentwicklungsmöglichkeiten werden diskutiert , aber zuerst möchten wir auf die Vorbereitungsphase kurz eingehen mit den Schritten Analyse und Entwurf. Für EntwicklerInnen empfehlen wir die neuste Version unseres JAVADOC ’s, eine kleine Erklärung dazu gibt es im Anhang. Wir möchten uns an dieser Stelle herzlich bei unserer Betreuerin Univ. Ass. Dipl.-Ing. Dr. Hilda Tellioglu Technische Universität Wien Institut für Gestaltungs- und Wirkungsforschung Multidisciplinary Design Group bedanken. Daniel TAHIN Matr.Nr.: 0226781 Studienkennzahl: E033535 Wien, 20. 04.2007 Oliver GROF Matr.Nr.: 0227374 Studienkennzahl: E066937 2. Analyse 2.1. Use Cases Da es mittlerweile ein breites Spektrum an Technologien gibt, die im Software Engineering eingesetzt werden können, ist es unerlässlich, dass man die Use Cases eindeutig, verständlich definiert. Die nachfolgenden Anwendungsfallbeschreibungen entstanden einerseits anhand der Gespräche mit unserer Betreuerin, andererseits anhand der Diskussionen im Team, bei denen es darum ging, einzelne Punkte möglichst genau zu definieren. Nr.:1 Titel: Artikelsuche mit Eingabe eines Suchbegriffes Kurzbeschreibung: In einem Textfeld wird ein Suchbegriff eingegeben und auf einen Button geklickt. Danach wird das Suchergebnis angezeigt. Vorbedingung: Die Seite wurde fehlerfrei in dem Webbrowser geladen, sie enthält zumindest ein Textfeld und ein Button zum anklicken. Beschreibung des Ablaufs: E1) AnwenderIn gibt mit der Tastatur einen beliebigen Suchbegriff ein. A1) Der eingegebene Text erscheint im Textfeld. E2) AnwenderIn startet die Suche mit dem OK-Button. A2) Das System benachrichtigt AnwenderIn, dass die Suche gestartet wurde und überprüft den Text im Textfeld. E3) Das Textfeld ist leer. A3) Das System benachrichtigt AnwenderIn, dass kein Suchbegriff eingegeben wurde. AE3) Das Textfeld ist nicht leer, die Suche wird durchgeführt. AA3) Suchergebnisse werden angezeigt oder eine Nachricht, dass nichts gefunden wurde. Auswirkungen: Das „Caching“ der Ergebnisse wird automatisch durchgeführt, in der Datenbank gibt es keine Änderungen – es handelt sich „nur“ um eine DB-Abfrage Anmerkungen: genaure Definition der Systemmeldungen ist Teil des Interaktionsdesigns Nr.: 2 Titel: Artikelsuche mit „typeahead“ (auf Tastendruck) Kurzbeschreibung: In einem Textfeld wird ein Suchbegriff eingegeben, die Suche wird automatisch nach Tastendruck durchgeführt und in einem eigenen Bereich dargestellt Vorbedingung: Die Seite wurde fehlerfrei in dem Webbrowser geladen, sie enthält zumindest ein Textfeld und ein Bereich für die Ergebnisse. Beschreibung des Ablaufs: E1) AnwenderIn gibt mit der Tastatur einen beliebigen Suchbegriff ein. A1) In dem ausgewählten Bereich werden die Artikel dargestellt, die mindestens eine Eigenschaft haben, die mit der eingegeben Charakterfolge beginnt. E2) AnwenderIn wählt ein Suchergebnis aus dem Bereich aus. A2) Die Auswahl wird angezeigt. Auswirkungen: keine, „nur“ die Darstellung Anmerkungen: genaure Definition der Systemmeldungen ist Teil des Interaktionsdesigns, das Caching ist einer der Weiterentwicklungsmöglichkeiten und dazu muss auch dieser Anwendungsfall eventuell neu definiert werden. Nr.:3 Titel: Anzeige der Details Kurzbeschreibung: Die Details eines gefundenen Artikels werden angezeigt. Vorbedingung: Die Suchergebnisse wurden fehlerfrei geladen, zu jedem Suchergebnis gibt es ein Hyperlink und/oder ein Button, die die AnwenderIn anklicken kann. Beschreibung des Ablaufs: E1) AnwenderIn klickt das Hyperlink oder das Button an (welches vorhanden ist). A1) Die Details werden angezeigt, dargestellt einem eigenen Bereich, möglichst ähnlich zu einem Desktop. E2) AnwenderIn klickt auf ein anderes Hyperlink (oder ein anderes Button) an. A2) Die Details des vorherigen Artikels werden versteckt und die Details des aktuellen Artikels werden Angezeigt. Auswirkungen: „nur“ die Darstellung Anmerkungen: Details werden aus dem Cache gelesen, E2 kann beliebig oft ausgeführt werden 2.2. Verwendete Technologien 2.2.1. Tapestry Tapestry ist ein komponentenbasiertes Framework und erlaubt die Entwicklung Javabasierender Webanwendungen. In Tapestry beschreiben drei Bestandteile eine Seite. Dies sind eine HTML-Vorlage, eine Seitenspezifikation und eine Javaklasse. Die Besonderheit der HTML-Vorlage ist, dass sie neben HTML-Tags spezifische Tapestry-Tags für den dynamischen Inhalt enthält. Es besteht also die Möglichkeit, dass GraphikerInnen an den statischen Inhalten und dem Design arbeiten können und EntwicklerInnen sich dem dynamischen Inhalt widmen können, ohne „sich in die Quere zu kommen“ Eine Hauptaufgabe der Seitenspezifikation ist, die Javaklasse festzulegen, die mit dieser Seite zu instanzieren ist. Anfang 2007 hat das Apache Tapestry-Team das Tapestry 5.0.1 veröffentlich. Die neue Version kommt laut [TAPESTRY5] gegenüber der Version 4 mit u.a. den folgenden Änderungen: • • • • • • • Komponentenklassen müssen nicht länger mehr auf Basisklassen aufsetzen. Komponentenklassen sind nicht länger abstrakt. Die Komponentenkonfiguration basiert nun auf Java-Annotations und nicht auf externen XML-Files. URLs sind jetzt kürzer und nützlicher dargestellt. Die Codepfade sind vereinfacht worden und die Runtime Reflection ist praktisch beseitigt worden. ein einfacheres Kodiermodell, welches auf dem Prinzip "Convention over Configuration" aufsetzt eine integrierte BeanEditForm-Komponente zum Entwickeln von einfachen Create/Update UIs 2.2.2. Google Webtoolkit und Widgets Google Webtoolkit (GWT) ist ein open source Java Framework, was die Entwicklung von Ajax Applikationen erleichtert. Ajax (Asynchronous JavaScript + XML) ist kein neue Technologie, sondern ein Marketing-Begriff, wurde von Jesse J. Garrett, Berater bei der amerikanischen Firma AdaptivePath eingeführt in Februar 2005. Es ist eine Sammelbegriff für die bestehende Technologien, die in Richtung von Web 2.0 zeigt, und bei vielen Webbrowsern unterstützt wird. Diese sind u.a.: y y y y y die Darstellung von Standard Webkomponenten, wie XHTML, CSS dynamische Darstellung und Interaktion unter Verwendung von Document Object Model (DOM) Informationsaustausch mit XML und XSLT asynchrone Datenübertragung mit XMLHttpRequest und JavaScript als die Verbindung zwischen diesen Wie an der Abbildung zu erkennen, besteht der Unterschied von Ajax zum klassischen Model darin, dass BenutzerInnen bei einer Anforderung nicht auf deren Ergebnis warten sollen. Technisch wird dies mit einem in JavaScript geschriebenen „Ajax engine“ realisiert. Hauptaufgaben von diesem Modul bestehen darin einerseits das momentan verwendete User Interface zu laden, andererseits die Kommunikation mit dem Server auf der Client-Seite zu unterstützen. Dadurch können BenutzerInnen mit der Webapplikation kommunizieren, als wäre sie eine herkömmliche Desktop-Anwendung, denn alle Benutzerinteraktionen erfolgen asynchron. Alle Antwort auf eine Benutzeranfrage, die keine direkte Serverinteraktion brauchen, wie zum Beispiel die Überprüfung von Werten in Eingabefeldern, modifizieren von Ergebnissen in Listen kann man dem Ajax engine überlassen. Erst, wenn neue Daten gebraucht werden, werden sie asynchron vom Server geholt, meistens im XML Format. Da Ajax im grössten Teil auf JavaScript beruht, ist es nicht immer einfach eine Webapplikation zu implementieren, die in den verschiedenen Webbrowsern funktioniert. Eine Browserunabhängige Lösung wird durch Google Webtoolkit angeboten. Im GWT es möglich ist Web Anwendungen komplett in Java zu schreiben. Dadurch kann man eine statische Type-Überprüfung erzielen, und die meisten Fehler beim Kompilieren erkennen. Das GWT generiert dann aus dem Java Code Browser-spezifische JavaScript und HTML Code, der dann in den gängigen Webbrowsern (Internet Explorer, Firefox, Opera, Safari) lauffähig ist. Einer der Vorteile von dieser Art der Entwicklung liegt an dem mitgeliefertem Browser mit dem es möglich ist die geschriebene Anwendung mit allen vorhandenen Java Debugging Möglichkeiten Schritt für Schritt zu debuggen. Weiters kann man die Java Sources in einem beliebigen JAVA-IDE, wie Eclipse entwickeln. Neben den bereits erwähnten Eigenschaften, hat GWT noch die folgenden, wichtigen Eigenschaften: y y y y y dynamische, wieder verwendbare UI-Komponente, die man aus eigenen, oder bereits bestehenden UI Bestandteile (Buttons, Checkboxes, Radio Buttons, Tables, Menus …) zusammensetzen kann. Ausser dem Standard GWT-UI Komponenten existiert noch zahlreiche widget-Sammlung. Eine davon ist das [GWT Widget Library]. RPC (Remote Procedure Call) framework für den einfachen, asynchronen Aufruf von Serverseitigen Funktionen. Dies beinhaltet noch die automatische Serialisierung/Deserialisierung von Anforderungen, bzw. Funktionsparametern und Rückgabewerten Browser history management. GWT ermöglicht das Zugreifen auf das „ZurückButton“ vom Browser, damit die Seite noch effizienter gestaltet werden kann Neben dem gewöhnten Debugging-Möglichkeiten, steht noch JUnit zur Verfügung, mit dem man sowohl im Debugger, als auch im Browser testen kann Möglichkeit zur Verwendung selbstgeschriebene JavaScript Codes unter Verwendung von JSNI (JavaScript Native Interface) bzw. HTML-Tags y Bietet die Möglichkeit um Applikationen zu internationalisieren, um für die verschiedene Sprachen anzupassen 2.2.3. MySQL/Hibernate Hibernate is ein leistungsfähige Object/relational mapping (ORM) Persistenz und Abfrage System. Hibernate ermöglicht das Erstellen von persistente Klassen unter Verwendung von Objektorientierte Paradigmen, wie Assoziierung, Vererbung, Polymorphismus, Komposition, und Kollektionen. Mit Hibernate ist es möglich Datenbankabfragen sowohl im SQL, als auch im eigenen SQL-Erweiterung (HQL) zu formulieren. Hibernate „befindet sich“ zwischen der Datenbank und einer Programmiersprache (Java, .NET) und bietet die Möglichkeit, die Daten eines Objektmodells auf ein relationale Modell und zu diesem passendes Schema abzubilden. Auf diese Weise lassen sich DB Tabellen in Klassenobjekten „konvertieren“, und komplexe relationale Zusammenhänge durch Objektmodelle und Funktionsaufrufe modellieren, wobei dieser Prozess für die BenutzerInnen transparent bleibt, damit mehr Zeit mit dem tatsächlichen Problem verbracht werden kann. Die wichtigsten Eigenschaften von Hibernate 3 sind wie folgt zusammengefasst: y y y y y y y y Unterstützung für EJB 3.0 Annotations, Entity Manager, und Java Persistence API Hibernate kann in jeden J2EE Applikationsserver arbeiten, und beim Bedarf kann über JMX (Java Management Extension) konfiguriert und überwacht werden. Man kann es natürlich außerhalb eines Applikationsserver einsetzen XML Bindung, die es ermöglicht Daten, als XML zu repräsentieren, und beschreibt sowohl die Datenbanktabellen, als auch die Verbindungen zwischen diesen. Hibernate unterstützt die in Datenbanken verwendete Abbildungen und Assoziierungen: 1-zu-N, 1-zu-1, N-zu-N. Ereignisbasiertes Design. Dadurch ist es möglich eigene Ereignisobjekte zu erstellen und zu bestimmten Szenario zuzuordnen Leistungssteigerung kann durch die zentrale Verwaltung von Persistenz erzielt werden. Ein two-layer caching System kann so aufgebaut werden, was das wirkungsvolle JBoss Cache verwendet Hohe Grad an Skalierbarkeit. Hibernate funktioniert sowohl in Einzel-Server Architekturen, als auch in verteilten Umgebungen Hibernate beinhaltet spezielle Mechanismen um die Zeitaufwendigsten Datenbankoperationen join, und union zu beschleunigen. Weiters wird das optimistische Sperren durch automatische Zeitstempelverfahren unterstützt. Durch die dual-layer caching Architektur wird thread-Sicherheit, nicht-blockierender Datenzugriff, und session level cache bereitgestellt, die besonders in verteilten Umgebungen wichtig sind, da dort mehrere Anwendungen gleichzeitig auf die DB zugreifen 2.2.4. CSS Cascading Style Sheets (CSS) ist eine deklarative Stylesheet-Sprache für strukturierte Dokumente. Sie wird vor allem zusammen mit HTML und XML (zum Beispiel bei SVG) eingesetzt. Ein Merkmal von XHTML ist die saubere Trennung von Inhalt und Gestaltung einer Webseite. Ein XHTML-Dokument enthält nur noch das, was auf der Seite erscheinen soll; ein dazugehöriges CSS-Stylesheet beschreibt, wie es dargestellt wird. CSS soll dabei festlegen, wie ein besonders ausgezeichneter Inhalt dargestellt werden soll. Dazu ist es wichtig, das HTML oder XML so zu gestalten, dass die Abschnitte, deren Aussehen gleich sein soll, auch als Gruppe erkannt werden können. Man zeichnet im Dokument also die Bedeutung einzelner Abschnitte aus, während das Aussehen dieser ausgezeichneten Abschnitte im CSS festgelegt wird. CSS ermöglicht es, die Darstellung dem jeweiligen Ausgabemedium (zum Beispiel Papier, Projektion, Sprache usw.) entsprechend anzupassen. Das ist nützlich, um zum Beispiel Hyperlinks beim Drucken extra aufzuführen, oder um für ein Anzeigemedium wie einen PDA oder ein Mobiltelefon mit geringerer Auflösung die Anzeige zu optimieren (geringere Seitenbreite und -höhe). Neben diversen Fähigkeiten im Farb- und Schriftbereich bietet CSS die Möglichkeit, Elemente frei zu positionieren oder Hintergrundbilder festzulegen. Das Konzept der Cascading Style Sheets (CSS) wurde 1994 von Håkon Wium Lie vorgeschlagen. Bert Bos arbeitete zu dieser Zeit an der Implementation eines Browsers namens Argo, der seine eigene Stylesheet-Sprache benutzte. Die beiden entschieden sich, zusammenzuarbeiten und CSS zu entwickeln. Es gab zu dieser Zeit auch andere Sprachen mit dem gleichen Ziel, CSS brachte aber als erste die Idee auf, Regeln zu definieren, die über mehrere Stylesheets hinweg vererbt werden konnten. Nach der Präsentation von CSS durch Håkon an der Konferenz „Mosaic and the Web“ in Chicago 1994, und später mit Bos 1995 wurde das World Wide Web Consortium (W3C) auf CSS aufmerksam. Håkon und Bos arbeiteten in diesem Rahmen an CSS weiter, zusammen mit anderen Mitgliedern, u. a. Thomas Reardon von der Firma Microsoft. Im Dezember 1996 wurde dann die CSS Level 1 Recommendation publiziert. Diese wird in aktuellen Browsern mittlerweile nahezu vollständig umgesetzt. CSS Level 2 (CSS2) wurde im Mai 1998 veröffentlicht. Bis heute wird diese Empfehlung noch nicht hinreichend von allen verbreiteten Browsern implementiert. Manche Browser setzen den größten Teil von CSS2 korrekt um, andere hingegen bieten nur eine mangelhafte Unterstützung von wenigen Teiltechniken. Bei der praktischen Anwendung im Web ergeben sich daher oft unnötige Schwierigkeiten. Momentan arbeitet das W3C an einer Zwischenversion CSS Level 2 Revision 1 (CSS 2.1), die die Erfahrungen mit CSS2 berücksichtigt, Unstimmigkeiten korrigiert und diejenigen Teiltechniken streicht, die bisher in verschiedenen Browsern nicht korrekt implementiert wurden. CSS 2.1 bringt selbst keine grundlegend neuen Fähigkeiten mit sich. Gleichzeitig ist CSS Level 3 in der Entwicklung. Hier werden die Entwicklungen weiter vorangetrieben, die bereits bei CSS2 gestartet wurden. CSS3 wird im Gegensatz zu den Vorgängern modular aufgebaut sein, d.h. einzelne Teiltechniken (beispielsweise zur Steuerung der Sprachausgabe) haben ihren eigenen Entwicklungsrhythmus und Versionsschritte. So nähert sich CSS bei seinen Fähigkeiten mehr dem etablierten DSSSL (für SGML) an und stellt wohl auch in Zukunft noch eine attraktive Alternative zu XMLbasierten Stylesheet-Sprachen wie XSL-FO dar. CSS gilt heutzutage als die StandardStylesheetsprache für das Web. Als ein Beispiel soll das auf dem Bild erscheinende PopupFenster die fähigkeit von CSS in Firefox demonstrieren. 2.2.5. Evaluierung Eine Herausforderung bei der Entwicklung einer Webapplikation ist es, das Produkt für alle(oder zumindest für alle populären) Browser funktionsfähig, genauer gesagt benutzbar im Sinne des Usability Engineerings zu machen. Ganz besonders wichtig ist, dass die vorhandenen Standards für HTML, CSS, usw. meistens nur die Struktur der Dateien festlegen und nicht die Darstellung dieser Dateien im Browser. Es ist also durchaus möglich, und eigentlich auch legitim, dass dieselbe Webapplikation in verschiedenen Browsern verschieden dargestellt werden kann. Eine besondere Problematik ist das Arbeiten mit Javascript, darum ist es ratsamer „schlaue“ Frameworks zu verwenden, die einem das oft lästige Script-Schreiben abnehmen und trotzdem dem AJAX-Paradigma gerecht werden. In August 2006, als wir mit dem Projekt begonnen haben, war Google Webtoolkit eines der Leistungsfähigsten Frameworks auf diesem Gebiet. Dieser ermöglicht es mit der Programmiersprache Java AJAX-Anwendungen zu erstellen, das benötigte Javascript wird automatisch vom Compiler erstellt und ist sofort für alle populären Browser funktionsfähig. Die relativ schnelle Weiterentwicklung (und relativ schnell steigende Versionsnummer) ist eine Bestätigung für uns, dass es sich hierbei auch in Zukunft um ein State-Of-The-Art Framework handelt. Um auf den neuesten Stand zu bleiben, haben wir im Februar 2007 die (zu dieser Zeit) neueste Version des GWT und den dazugehörigen GWTWidgets in unser Projekt integriert. Wir mussten jedoch keine speziellen Änderungen im Sourcecode vornehmen. Wie schon oben erwähnt, haben wir mit dem Projekt im August 2006 begonnen. Zu dieser Zeit war die aktuellste Version von Tapestry 4.0 und bei der Entwicklung stützten wir uns auf [TONG], eines der neusten Bücher auf dem Markt zu dem Thema, das auch mit Tapestry4 arbeitet. Bei den weiteren Entwicklungen empfehlen wir die Verwendung der neueren Version. Versionsnummern der Verwendeten Technologien Google Webtoolkit 1.2.22 Google Webtoolkt Widgets 0.1.3 Tapestry 4.0 3. Entwurf 3.1. Entwurf der Geschäftslogik Nachdem wir in dem Arbeitsschritt „Analyse“ die Technologien, die zum Einsatz kommen sollen, unter die Lupe genommen und evaluiert haben, möchten wir uns beim Entwurf auf diese Erkenntnisse stützen und sozusagen einen Plan für die Implementierung erstellen. Aufgrund der Frameworks, für die wir uns entschieden haben ist eine bestimmte Struktur bezüglich der Packages, Ordner, Filenames schon vorgeben. Da wir vorher das Framework Tapestry nicht verwendet haben und uns erst in das Gebiet einarbeiten mussten, ist hier auf jeden Fall klarzustellen, das wir uns bei der Entwicklung auf [TONG] stützten und eventuelle Namensgebung, wie zum Beispiel der Packagename com.ttdev.* hier entnommen wurde. Auch der Kontext der Hauptkomponente ist Home.html genannt, und die XML-Datei für die Seitenbeschreibung heißt Home.page. Insgesamt werden drei packages neu implementiert werden müssen. Außer dem Package für die Tapestry Klassen (com.ttdev.publikation), benötigen wir noch je ein Package für die GWT Client-Seite und für die GWT-Server Seite. Welche Klassen wir in den einzelnen Packages implementieren müssen, haben wir in den folgenden Tabellen zusammen geschrieben. Package: com.ttdev.publikation (Tapestry) Name der Klasse Home Beschreibung, Aufgabe Die Javaklasse, die mit der Seite zu instanzieren ist, wird von Home.page festgelegt. Suchklasse Um eine klare Trennung zwischen Darstellung und Datenbank zu haben, ist eine Javaklasse zu implementieren, die Methoden für die Suchen enthält ResultObject Klasse um die Suchergebnisse zu speichern (Caching) Komponentklasse(n) Falls weitere Komponente in Tapestry definiert werden, müssen die auch Javaklassen haben, die die Funktionalitäten festlegen weitere Klassen Weitere logische Teile, die zwecks Übersichtlichkeit und gute Erweiterbarkeit in eigene Klassen definiert sein müssen Package: com.ttdev.gwtpublikation.server (GWT-Server) Name der Klasse Suchklasse Beschreibung, Aufgabe Um eine klare Trennung zwischen Darstellung und Datenbank zu haben, ist eine Javaklasse zu implementieren, die Methoden für die Suchen enthält. Die Suche geschieht logischerweise auf der Server-Seite, die Kommunikation läuft über ein Interface, das diese Suchklasse implementiert weitere Klassen Weitere logische Teile, die zwecks Übersichtlichkeit und gute Erweiterbarkeit in eigene Klassen definiert sein müssen Package: com.ttdev.gwt.publikation.client (GWT-Client) Name der Klasse MainPage Typeaheadsuche Detailsanzeige Interface(s) Weitere Klassen Beschreibung, Aufgabe Einstiegsmodule für Google Webtoolkit Klasse für die Typeaheadsuche Klasse für die Anzeige der Details Interface(s) für die Kommunikation mit dem Server Weitere logische Teile, die zwecks Übersichtlichkeit und gute Erweiterbarkeit in eigene Klassen definiert sein müssen Minimaler Inhalt von dem Ordner „Context“ Home.html Home.page styles.css Webbrowser Client-Seite User Interface Typeahead HTML-Inputfield GWTServlet Tapestry-Servlet Sessions-Cache Hibernate Datenbank (MySQL) Apache Tomcat Abbildung: Entwurf der Systemarchitekur des Webportals Server-Seite 3.2. Interaktionsdesign Bei der Entwicklung von interaktiven Produkten sollte man die Aspekte des Interaktionsdesigns nicht ungeachtet lassen. Da es auf dem Gebiet des Informations- und Interaktionsdesign sogar in Fachkreisen hin- und wieder umstrittene Definitionen gibt, möchten wir hier auch nicht ins Detail gehen. Unumstritten ist allerdings, dass es die Mensch-Computer Interaktion, als solches gibt und die Entwicklung nur sinn macht, wenn man effiziente, benutzbare Produkte erstellt. Das Interaktionsdesign wird sowohl in der deutschen, als auch in der englischen Literatur mit der Erfahrung, mit dem Erlebnis (Experience) ergänzt. Aufgrund der Anzahl und des Karakters unserer Anwendungsfälle haben wir es nicht nötig gefunden, umfassende Interaktionsstudien(wie z.B. Befragungen der zukünftigen BenutzerInnen, usw.) bei der Analyse durchzuführen und dem entsprechend unser Systemdesign vorzunehmen. Wir strebten aber von Anfang an, die Anwendung benutzerfreundlich und benutzbar zu gestalten, worunter wir ein einfaches, leicht verständliches User-Interface und eine optimale Informierung der BenutzerInnen verstehen. Wichtig ist natürlich auch, das die Positionierung der Elemente so erfolgt, dass die BenutzerInnen möglichst auf einer natürlichen Weise auffinden können. Wir sind überzeugt, dass dies auch zu dem oben genannten „Erlebnis“ beiträgt. Nachfolgend möchten wir die wichtigsten Beispiele aus der Applikation vorführen. Obwohl eines unserer Primärziele war, die Geschwindigkeit der Abfragen möglichst optimal zu halten, kann es aufgrund der Größe der Datenbank zu kürzeren Wartezeiten kommen. BenutzerIn wird benachrichtigt, dass die Anfrage bearbeitet wird. Beim typeahead(Suchtipp) Teil wurde auch auf die Aspekte des Interaktionsdesign geachtet. Die erste Zeile beinhaltet Informationen für BenutzerInnen, wie „Kein Treffer“ „Schnellsuche nach…“, „Ergebnisse für..“ . Außerdem hat unser Entwicklungsteam darauf geachtet, dass die Positionierung und die Größe optimal sind. Bei der Schnellsuche wurde auch auf das Interaktionsdesign geachtet Nach einer „normalen“ Suche werden alle wichtigen Informationen der Suchergebnisse betreffend dargestellt. BenutzerIn weiß eindeutig, wie viele Treffer seine Suchabfrage hat und auf welcher Seite er zurzeit ist. 4. Implementierung 4.1. Status Das Webportal besteht aus 2 Haupteinheiten. Home.java ist für Tapestry, MainPage.java ist für Google-Webtoolkit (GWT). Tapestry haben wir verwendet, um die Generierung von HTML-Inhalten zu vereinfachen, und GWT, um eine angenehme Benutzer-Interaktion Mithilfe von JavaScript in möglichst vielen Webbrowsern zu unterstützen. 4.1.1. Tapestry Um die Seite „Suchen in der Publikationsdatenbank“ zu beschreiben, haben wir Home.html, Home.page, Home.java erstellt. Sie ist erreichbar unter http://server:port/path-topublikation/app . Nachdem man dieses URL im Adressleiste des Browsers eingetippt hat, kann man drei verschiedene Ereignisse unterscheiden. Beim Aufbau der Webseite, werden alle dynamische HTML-Komponente durch Tapestry generiert. Diese sind im wesentlichen das HTML-Form-Element, und das HTMLEingebefeld (<form jwcid="queryForm"> bzw. <input id="inputField" jwcid="queryTextField" displayName="Publication" size="30"/>). Die entsprechende Tapestry-Binding Komponente befinden sich im Home.page, wo „jwcid” von dem HTMLTag das Tapestry-Binding-component bezeichnen. Bei einer Suchanfrage (also beim Klicken auf das Button „Ok“) wird eine HTTP-POST Anforderung von Browser an Server geschickt, die das Aufrufen von public IPage onOk(IRequestCycle cycle)@Home.java bewirkt. Hier wird nach dem eingegebenen Suchkriterium gesucht, und das Ergebnis dargestellt (weitere dynamische HTML erzeugt). Wurde nichts gefunden, wird „<span class="info" jwcid="sv"/>“ durch public String getSv() gefüllt. Ansonsten werden die Ergebnisliste „<div jwcid="eachEntry">“ (durch public List getEntries(), public String getMyHyperlinkBegin(), public String getMyHyperlinkMiddle(), public String getMyHyperlinkEnd()) und die Verweise am Seitenende „<span jwcid="linkBar">“ (durch public String[] getLinkBarSource(), public List getLoadIndex()) aufgebaut. Wenn das eingegebene Suchstring ein leeres String ist, wird eine Fehlermeldung angezeigt. Die dafür verantwortliche HTML-Komponente ist „<span jwcid="empty_searchkey_error">“ bzw. public String getEmptySearchkeyErrorMsg(). Blättert man durch die Ergebnisseiten, passiert ähnliches, als bei einer Suchanfrage. Zunächst einmal ruft Tapestry public void loadResults(int LRindex, long sid) auf, was als eine „listener“-Funktion vom Tapestry-component (mit ID: linkid) registriert ist. Danach wird die ganze Seite neu aufgebaut, und damit auch alle Tapestry-Komponente neu ausgewertet. Beispielsweise wird dann „<div jwcid="eachEntry">“ mit den Ergebnissen von den neulich gewählten Seite aufgefüllt. Im Wirklichkeit, wenn die Seite neu geladen wird, z.B durch Auswählen einer neuen Ergebnisseite, werden die auf dem Seite befindlichen Tapestry-Komponente neu ausgewertet. Dies ist kein Widerspruch zu den oben beschriebenen drei Fällen, denn wenn z.B. nichts gefunden wurde, retourniert getEntries() null, und so weiss Tapestry, dass „nichts zu Tun gibt“ und bleibt „<div jwcid="eachEntry">“ leer. 4.1.2. Google Webtoolkit Um allgemein GWT in einem normalen HTML Dokument einbetten zu können, muss man die folgende Zeilen <meta name='gwt:module' content='com.ttdev.gwtpublikation.gwtajax'> <link rel=stylesheet href="styles.css"> zwischen den <head></head> Tags als erstes, bzw. <iframe id='__gwt_historyFrame' style='width:0;height:0;border:0'></iframe> <script language="javascript" src="gwt.js"></script> ganz am Anfang vom <body> Tag einfügen. Man soll ausserdem die Dateien gwt.js und styles.css ins selbe Verzeichnis platzieren, wo die HTML-Datei befindet, die den Verweis auf diese beiden hat. Besteht die Webapplikation aus mehreren HTML-Templates, müssen in jeder diese Zeilen eingefügt werden! gwt.js ist ein vorprogrammiertes Modul, was in jedem GWT-Paket vorhanden ist. Seine Aufgabe ist es, das GWT-System zu initialisieren; u.a. den Browser-Typ abzufragen. Nachdem diese Vorarbeit geleistet wurde, kann mit der Implementierung begonnen werden. Um Tapestry und GWT gemeinsam verwenden zu können, ist es sinvoll, bestimmte HTMLElemente mit einem eindeutigen Bezeichner (ID) zu versehen. So kann man diese Elemente im GWT unter Verwendung von DOM leicht „auffinden“. Als erstes, muss man der aktuellen Seite eine ID zuweisen. Da im GWT 1.3 nur ein Entrypoint geben kann, muss man die Seiten voneinander unterscheiden, um in public void onModuleLoad() sinvolle Funktionen realisieren zu können. Nachdem die ganze Webseite vollständig geladen wurde, wird GWT „aktiviert“ durch den Aufruf von onModuleLoad(). Diese ruft des Weiteren public void init() in ArticleSearch.java auf. Hier ist es wieder nützlich, wenn man IDs gesetzt hat, denn das Eingabefeld, das Ok-Button, und die Details-Buttons werden gesucht, und verwendet. Erst wenn ein Element gefunden wurde, kann man ihm bestimmte Funktionen zuweisen. So beispielsweise in public void onClick(Widget sender) wird die Meldung „Warten auf Antwort...“ gezeigt, wenn das Ok-Button neben dem Eingabefeld gedrückt wurde. Weiters wird hier die Anforderung für die Detailsanzeige am Server gesendet. Um die Details abfragen zu können, hat jede <button> - Tag ein „name“ – Attribut, die wie folgt aufgebaut sind: sessionid:articleid . Eine der wichtigsten Konzepte von GWT ist der RPC (Remote Procedure Call) Mechanismus, was wir auch verwendet haben. RPC ermöglicht eine einfache Verwendung von Client-Server Kommunikation. Dadurch kann man eine Funktion, die physikalisch auf einem anderen Computer läuft, aufrufen, als wäre sie lokal vorhanden. Dies gilt auch für die Parameterübergabe, bzw. für die Rückgabewerte. Um RPC bei einer Funktion verwenden zu können, muss man zwei Interfaces für diese Funktion erstellen. Eine von den beiden wird an der Server-Seite implementiert, und das andere wird an der Client-Seite benutzt. Bei unserem Fall sieht das zum Beispiel für die Funktion searchDb(String s) wie folgt aus. searchDb(String s) wird sowohl im IService.java, als auch im IServiceAsync.java deklariert. IService wird durch SearchDb.java auf die gewöhnte Weise implementiert, und IServiceAsync wird im ArticleSearch.java verwendet, um ein Objekt, namens sendTypeaheadQueryTo zu erstellen. Auf dieses Objekt kann man schon searchDb(String s) aufrufen, aber vorher muss man noch ein AsyncCallback-Objekt erstellen, was als zusätzlicher Parameter an searchDb(String s) übergeben wird. Deswegen steht searchDb(String s, AsyncCallback callback) in IServiceAsync.java. Dieses Objekt wird dann die “Antwort” vom Server erhalten und abarbeiten, da die Antwort immer asynchron ankommt. Bei uns hat dieses Objekt die Name typeaheadCallback. Solche Objekte müssen immer die zwei Funktionen public void onFailure(Throwable caught) und public void onSuccess(Object result) implementieren, wo die tatsächliche Abarbeitung in der letzteren geschieht. Auf diese Weise wird die Programmabarbeitung nicht solange aufgehalten, bis die Antwort vom Server ankommt, und die BenutzerInnen können andere Dinge erledigen. 4.2. Spezielle Features Timer beim Typeahead(Schnellsuche): Bei der ersten Version unserer Schnellsuche wurde nach jedem Tastendruck in der Datenbank gesucht. Das heißt, wenn man zum Beispiel das Stichwort „Politik“ eingegeben hat, wurde hintereinander nach „p“, “po“, “pol“ …usw. und schließlich nach „Politik“ gesucht. Wenn der User das Wort Politik ohne größere Pausen eintippt, ist er sicher nicht an „Teilergebnissen interessiert, der Server wird aber dadurch unnötig belastet und die Suche wird wahrscheinlich verlangsamt. Bei der aktuellen Version ist daher ein Timer eingebaut, der gestartet wird um zu sehen, um bereits eine kleine Pause(1000ms) beim Eintippen gemacht wurde oder nicht. Falls ja, wird die Suche gestartet und die Ergebnisse werden dargestellt. Caching bei der Suche: Mit Hilfe von den verwendeten Technologien(siehe dazu 2.2) ist es möglich, die Suchergebnisse zu cachen und auf sie schnell zuzugreifen. Ein wichtiger Teil hierbei ist die Implementierung der ResultObject Klasse, die für einen eingegebenen Suchbegriff die Ergebnisse speichert. In der aktuellen Version wird auch bei der Detailanzeige auf diese gecachten Daten zugegriffen, was durchaus als eine Optimierung der Ressourcenausnutzung angesehen werden kann. Sessionmanagement: Natürlich ist es möglich, das Webportal in mehreren Browserfenstern (bzw. -tabs) zu öffnen und mehrere Suchen zu starten, die wiederum mehre Seiten als Ergebnis liefern. Ganz wichtig haben wir also das Feature Sessionmanagement empfunden. Um alte Sessions zu löschen, wird ein separater Thread gestartet, sobald eine Suche durchgeführt wurde und die Suchergebnisse gespeichert wurde. In diesem Thread wird in einem bestimmten Intervall immer geprüft ob es Sessions gibt, die bereits älter sind, als die so genannte „aktive Zeit“, falls ja werden die betroffenen Sessions gelöscht. Wenn zum Beispiel alle fünf Minuten kontrolliert werden soll, ob die Session älter als 20 Minuten sind, müssen die Konstanten im Code folgendermaßen definiert werden: final long activeTime=1200000;//=20 min final long threadTime=300000;//=5 min 4.3. Problembericht • Um ein existierendes HTML-Element im GWT verwenden zu können, brauchten wir ein zusätzliches Package, das „GWT Widget Library“. Dies war unerlässlich, denn zum Beispiel muss man im GWT den Inhalt vom Eingabefeld ([email protected]) auslesen. • Manchmal trat bei der Schnellsuche ein „InvocationException“ auf. Jedoch keine schwerwiegende Ausnahme. Es passierte dann, wenn die Schnellsuche noch läuft, aber gleichzeitig auf „Ok“ geklickt wurde. Um diese zu vermeiden, war es nötig, die Schnellsuche zu deaktivieren, sobald „Ok“ angeklickt wurde. • Für jedes Button ein onmouseover/onmouseout Attribut hinzugefügt. Dies war nicht so eindeutig mit GWT, denn die Funktion setAtribute()@com.google.gwt.user.client.DOM hat nicht das erwartete Ergebnis geliefert. Stattdessen müssten wir dem JSNI von GWT zuwenden, und die Javascripts selbst zu erstellen. Es wird zuerst nach den Buttons gesucht, und in ein WButtonObjekt umgewandelt (siehe searchArticleHyperlinks()@ArticleSearch.java). Damit wird jedoch eine GWT-Spezifische „Variante“ von diesem Button erstellt, und wenn man später Funktionen, wie das Verhalten, wenn der Mauszeiger über das Button bewegt wird zuwiesen möchte, muss man direkt auf das Objekt zugreifen, was im Browser’s DOM zu finden ist. • Für die Darstellung von internationalen Zeichen, wie ü, ö … bietet GWT keine Unterstützung, obwohl im HTML die Möglichkeit dafür besteht. So musste man statt ü, &#252; verwenden (siehe onSuccess()@ArticleSearch.java). • Tomcat produzierte oft OutofMemory Errors. Der Fehler lag an der ungeeigneten Konfiguration (siehe Einstellungen im setclasspath.bat). • Es traten Probleme bei der Einbindung von Scrift im Eclipse auf (die Ursache war wahrscheinlich, dass das scrift.jar in einem Verzeichnis war, dessen Name Leerzeichen enthalten hat). • Eine Verzögerung bei der Schnellsuche war nötig, weil ohne dieser die Anforderungen zu oft am Server geschickt wurden, und zu einer unnötigen Belastung der Ressourcen führten. • Das Suchen in der Liste von Schnellsuche ([email protected]) mit der Funktion getSelectedIndex()@com.google.gwt.user.client.ui.ListBox funktionierte nur im Firefox, weshalb eine andere (langsamere) Lösung zu finden war (siehe echoSelection()@ArticleSearch.java). • Um die SessionID für die Suchergebnisse einzustellen haben wir zuerst eine eigene Funktion in Home.java eingebaut. Diese hatte den großen Nachteil, dass dann das SessionID von jeden bisher angeforderten Suchergebnissen verändert wurde. Ursache dafür war die Tatsache, dass jedes mal, wenn die Seite „Suchen in der Publikationsdatenbank“ aufgerufen wird, wird eine neue Instanz von Home.java generiert. Deswegen muss man das Setzen von SessionID auch separat behandeln, in der Datei Home.page. • Um Scrift benutzen zu können, braucht man nicht nur Hibernate zu konfigurieren, sondern die folgende Codezeilen: Configuration conf = new Configuration(); Configuration okConf = new Configuration(); okConf=conf.configure(); HibernateUtil.setConfiguration(okConf); sonst bekommt man überall NullPointerExceptions (siehe SearchPub.java). 5. Testen Das Testen haben wir unter folgenden Betriebssystemen bzw. Webbrowsern durchgeführt: MS Windows XP Linux/Fedora 4 Firefox Opera 1.5, 2.0 9.10 MS Internet Explorer 6.0, 7.0 1.0 8.0 - Bei den aufgelisteten Browsern hat es keine signifikanten Unterschiede bezüglich der Darstellung gegeben, mit Ausnahme von Opera. Dort hatten wir das Problem, dass die Details-Anzeige immer am Seitenanfang gezeigt wurde. Sogar beim letzten Artikel. In der endgültigen Version haben wir dies korrigiert, um ein akzeptables Resultat zu erzielen. 6. Verbesserungs- und Weiterentwicklungsmöglichkeiten Obwohl wir ständig an der Verbesserung des Webportals gearbeitet haben und darauf geachtet haben möglichst viele der aufgetauchten Probleme zu lösen, gibt es einige Verbesserungs- und Weiterentwicklungsmöglichkeiten, die zu aufwändig waren um diese im Rahmen dieses Praktikums zu realisieren. Um das Webportal noch angenehmer zu gestalten und die Ressourcen noch effizienter auszunutzen, sind einige wichtige Funktionalitäten zu implementieren. y Bei der Schnellsuche wird jedes Mal die Datenbank abgefragt. Dabei könnte man eine Effizienzsteigerung erreichen, indem man das Suchen nur Teilweise Hibernate überlässt. Nehmen wir an, die folgenden Sucheingaben wurden am Server geschickt: „wiss“ „wissen“ „wissenschaft“. Die Verbesserungsmöglichkeit liegt an der Hand. Bei „wissen“ und „wissenschaft“, da beide mit „wiss“ beginnen, könnte man von einer lokalen Cache lesen und erst dann die Datenbank bzw. Hibernate verwenden, wenn keinen Treffer im Cache gibt. y Ein weiterer Aspekt wäre die Schnellsuche und die „normale“ Suche zu „synchronisieren“. Sucht man mit Hilfe der Schnellsuche, und klickt man auf „Ok“, während die Daten noch nicht im Browser da sind, sieht man das Ergebnis nicht. Dies wäre durch deaktivieren des „Ok“ Buttons während der Schnellsuche vermeidbar und gleichzeitig die Option bieten, den Suchvorgang abzubrechen, um „Ok“ wieder betätigen zu können. Hier sind natürlich noch weitere Überlegungen nötig, welches Verhalten am optimalsten ist. y Bei der Schnellsuche wäre es noch sinnvoll, die Anzahl der Suchergebnisse auf eine bestimmte Weise zu begrenzen. Unserer Ansicht nach würde es genügen, 20-30 Treffer gleichzeitig darzustellen. Es ist vorteilhaft extrem lange Bearbeitungszeiten zu vermeiden, da während dessen der Browser blockiert ist, und keine Anforderungen akzeptiert. Es stellt sich natürlich die Frage, inwiefern das Webportal für zukünftige Projekte nützlich sein kann, welche Erkenntnisse gewinnen werden können und wie diese Erkenntnisse genutzt werden können um ein modernes AJAX-Applikation zu entwickeln. Erstens kann unsere „Suchmaschine“ als eine große Komponente angesehen werden, der als Teil einem komplexeren System fungieren kann. Interessant ist aber, ob mit unserem Ansatz auch weitere Use-Cases implementierbar sind und diese Implementierungen leistungsfähig und state-of-the-art sind. Aufgrund der nahezu unendlichen Möglichkeiten in der Software Entwicklung ist es nicht möglich eine vollständige Evaluierung durchzuführen und daher kann auch nicht eindeutig gesagt werden, welche Ansätze, Methoden, Technologien die beste Lösung bilden. Was wir in dem Projekt gezeigt haben, war ein Ansatz, wie die Frameworks Google Web Toolkit und Tapestry zusammen verwendet werden können. Das Produkt kann also auch als eine Basis für ein größeres System angesehen werden, bei dem durch Hibernate auch weitere Operationen(einfügen, löschen) ausgeführt werden können. 7. Anhang A: JAVADOC Sowohl Google Webtoolkit, als auch Tapestry sind so genannte Java Frameworks, d.h. sie erleichtern die Entwicklung eines AJAX-Webportals, in dem sie die Möglichkeit bieten, JavaKlassen effizient einzusetzen. Das (End)Produkt ist also dem „Asynchronous Javascript and XML“-Paradigma gerecht und sollte so leistungsfähiger sein. Das von uns entwickelte Webportal wird ja relativ ausführlich in dieser Dokumentation vorgestellt, den EntwicklerInnen soll aber die Weiterentwicklung mit dem „mitgelieferten“ JAVADOC erleichtert werden. Wir möchten aber darauf hinweisen, dass der Source-Code außer den JAVADOC-Kommentaren( /** Text**/ ) noch weitere „normale“ Kommentare (/* Text*/ bzw. //Text ) enthält. Diese sollten bei der Implementierung weiterer Klassen auch beachtet werden. Wie schon in weiter oben erläutert, gibt es 3 packages : com.ttdev.gwtpublikation.client com.ttdev.gwtpublikation.server com.ttdev.publikation. Zu allen drei wurde ein JAVADOC erstellt, das bekannte „tree“ und die Package-Übersicht sind inbegriffen. 8. Anhang B: Literaturangaben [TAPESTRY5] = Apache Tapestry 5, http://tapestry.apache.org/tapestry5/ ,zuletzt besucht am 15.02.2007 [TONG] = Tong Ka Iok, Kent: Enjoying Web Development with Tapestry, First Edition (2005) TipTec Development [MANNING] = Dave CRANE, Eric PASCARELLO, Darren JAMES: Ajax in Action (2006) Manning Publications Co. [GWT Widget Library] = http://gwt-widget.sourceforge.net/, zuletzt besucht am 19.02.2007 [AJAXWIKI] = http://en.wikipedia.org/wiki/Ajax_(programming), zuletzt besucht am 19.02.2007 [WEBTOOLKIT] = http://code.google.com/webtoolkit/, zuletzt besucht am 20.04.2007 [HIBERNATE] = http://www.hibernate.org, zuletzt besucht am 20.04.2007 [HIBERNATEB] = http://www.jboss.com/pdf/HibernateBrochure-Jun2005.pdf, zuletzt besucht am 20.04.2007 [CSSWIKI] = http://de.wikipedia.org/wiki/Cascading_Style_Sheets, zuletzt besucht am 20.02.2007 [CSSPLAY]=http://www.cssplay.co.uk/menu/alert.html#nogo, zuletzt besucht am 20.04.2007