komplexe web-anwendungen mit „struts”
Transcription
komplexe web-anwendungen mit „struts”
s c h we r p u n k t ko m p l exe web-anwendungen mit „struts” mehr zum thema: www.sdm.de/research von christian kamm und carsten klein KOMPLEXE WEB-ANWENDUNGEN MIT „STRUTS” Das Open-Source-Framework „Struts” eignet sich gut für einfache, zustandslose WebAnwendungen. Für komplexe Anwendungen mit zustandsbehafteten Dialogen trägt dieser Ansatz nicht. Zum einen bietet Struts keine Unterstützung für eine Zustandshaltung im Dialog, zum anderen führt der naive Einsatz von Struts zu einer starken Vermischung von Anwendungslogik und Technik. In dem Artikel wird gezeigt, wie man Struts um eine Dialogschicht erweitert und damit auch komplexe Web-Anwendungen beherrschbar macht. Die unterschiedlich schnellen Innovationszyklen von Fachlichkeit und Technik stellen ein Grundproblem in der Softwaretechnik dar: Während sich die technische Basis in ständigem Wandel befindet, bleiben die Anwendungen in ihrem Kern oft über Jahre hinweg stabil. Die Blueprints der Produkthersteller (vgl. [Sad00], [Kas00]) sind dabei wenig hilfreich. Sie fokussieren zu sehr die gerade aktuellen Technologien oder den Einsatz ihrer Produkte und beschränken sich meist auf die Angabe von Anwendungstopologien. Antworten auf diese Kernfrage des Softwaredesigns für betriebliche Informationssysteme bieten sie nicht. Dabei hat Dave Parnas bereits 1972 die passende Antwort formuliert: Software, die sich unterschiedlich schnell ändert, wird in unterschiedliche Module aufgeteilt (vgl. [Par72]). Die Firma sd&m hat dieses Grundprinzip von Parnas für betriebliche Informationssysteme konkretisiert (vgl. [Sie00], [Brö99]). Die Software-Blutgruppen stellen ein verlässliches Instrument zum Erstellen und Bewerten von Softwarearchitekturen dar (siehe Kasten 1). Die Kernaussage der BlutgruppenTheorie ist, dass man anwendungsspezifischen Code (A-Code) und technikspezifischen Code (T-Code) in der Architektur strikt trennen sollte, um Erweiterbarkeit und Wartbarkeit zu garantieren. Gerade bei Benutzungsschnittstellen ist diese ATTrennung wichtig: Hier gibt es keinen anerkannten technischen Standard, wie z.B. SQL für Datenbanken. Stattdessen gibt es eine Vielfalt von proprietären und oft unausgereiften APIs für Benutzungsschnittstellen (UI-APIs), die sich in jährlichem Rhythmus ändern. Bei einer zu starken Kopplung von Anwendung und UI-API muss bei einem Wechsel der API nicht selten die ganze Anwendung neu gebaut werden. Für Web-Anwendungen mit Java sind Java Server Pages (JSPs) und Servlets der Stand der Technik. Das Open-Source- 26 27 Framework Struts hilft beim Erstellen web-basierter Anwendungen, indem es die Trennung der Zuständigkeiten von Model, View und Controller in der Architektur etabliert (vgl. [Brow01], [Str02]). Ein Vergleich verschiedener Web-Frameworks findet sich unter [Bar02]. Im Folgenden skizzieren wir den Leistungsumfang von Struts und stellen die Stärken und Schwächen dieses Frameworks dar. Anschließend zeigen wir, wie man durch das Einführen einer technikneutralen Dialogschicht die Kopplung zwischen Anwendung und JSP/Servlet-API reduziert und damit in der Architektur an Flexibilität gewinnt. Was bietet Struts? Struts ist ein Open-Source-Framework für Web-Anwendungen, die auf JSP/ServletTechnik basieren. Struts wird im JakartaProjekt der Apache-Gruppe entwickelt (vgl. [Str02]) und implementiert die Model-2-Architektur (vgl. [Brow01]), eine Variante des MVC-Patterns. Aufwand und Nutzen Das Struts-Framework bietet dem Nutzer eine konfigurierbare Aktionssteuerung, die eingehende HTTP-Anfragen auf anwendungsspezifische Aktionen abbildet. Diese Aktionssteuerung wird über eine XML-Datei konfiguriert. Struts unterstützt bei der Entwicklung von formularbasierten Oberflächen. So werden z. B. Benutzereingaben automatisch aus der HTTP-Anfrage ausgelesen und serverseitig in anwendungsspezifische Formulare (ActionForms) übernommen. Optional wird dabei eine formularbasierte Validierung am Server durchgeführt. Außerdem stellt Struts umfangreiche Tag-Bibliotheken zur Verfügung, die das Erstellen der JSPs vereinfachen. Diese TagBibliotheken bieten unter anderem Unterstützung für Iteratoren, das Erstellen und Manipulieren von JavaBeans und die Internationalisierung von Meldungen. d i e a u t o re n Christian Kamm (E-Mail: christian.kamm@sdm.de) ist Berater bei der sd&m AG. Sein technisches Schwerpunktthema ist die Konstruktion von grafischen Benutzungsschnittstellen. Carsten Klein (E-Mail: carsten.klein@sdm.de) hat mehrjährige Erfahrungen in der Leitung von Projekten und dem Design objektorientierter Systeme. Derzeit ist er Wissens-Broker für Clientarchitekturen bei sd&m Research. Das Struts-Framework erwartet vom Nutzer, dass er die Aktionssteuerung konfiguriert und die anwendungsspezifischen Struts-Aktionen (Action) und StrutsFormulare (ActionForm) implementiert. Struts ist ein schlankes Framework, das im Wesentlichen aus sechs zentralen Klassen besteht (siehe Abb. 1). Es etabliert eine gute Trennung von Außen- und Innensicht, sodass der Lernaufwand gering ist. Nach zwei Tagen hat man Struts verstanden. Dabei helfen die gut dokumentierten StrutsQuellen und die Beispielanwendungen. Struts-Komponenten Die zentrale Klasse von Struts ist das ActionServlet. Es implementiert die Aktionssteuerung der Anwendung. Das ActionServlet nimmt alle eingehenden HTTP-Anfragen der Anwendung entgegen, führt die zugehörigen fachlichen Aktionen (Action) aus, und leitet zu den JSPs weiter, die die HTTP-Antwort erzeugen. Bei Eingabeformularen (HTML-Forms) werden vor dem Ausführen einer Aktion die Benutzereingaben aus der HTTP- w w w. o b j e k t s p e k t r u m . d e s c h we r p u n k t ko m p l exe web-anwendungen mit „struts” Was bietet Struts nicht? Blutgruppen Software, die sich mit verschiedenen Dingen gleichzeitig befasst, ist in jeder Hinsicht schlecht. Ein Paradebeispiel dafür im Umfeld von Web-Architekturen ist der seitenzentrierte Ansatz. Eine JSP umfasst bei diesem Ansatz nicht nur Layout-Informationen und die Dialogsteuerung, sondern auch noch Anwendungslogik, Datenbankzugriffe und Fehlerbehandlung. Die Idee der Zuständigkeitstrennung (Seperation of Concerns) kann man formalisieren: Jedes Softwaresystem befasst sich mit der fachlichen Anwendung, denn dafür wurde es gebaut, und es verwendet eine technische Basis (Betriebssystem, Datenbank, Verbindungssoftware), denn im luftleeren Raum kann es nicht laufen. Daher gehört jede Komponente zu genau einer von vier Kategorien: 0-Software ist unabhängig von Anwendung und Technik. Beispiele sind Klassenbibliotheken, die sich mit Strings und Behältern befassen, etwa die zum C++-Standard gehörige „Standard Template Library” (STL). Sie ist ideal wiederverwendbar, für sich alleine aber ohne Nutzen. A-Software ist bestimmt durch die Anwendung, aber unabhängig von der A Technik. Anwendungsbestimmter Code kennt Begriffe wie „Fluggast”, „Buchung” oder „Fluglinie”. T-Software ist unabhängig von der Anwendung, aber bestimmt durch die T Technik: Ein solcher Baustein kennt mindestens eine technisches API wie JDBC, JSP oder Servlet. AT-Software ist bestimmt durch Anwendung und Technik: leider eine häufig AT anzutreffende Form. Sie ist schwer zu warten, widersetzt sich Änderungen, kann kaum wiederverwendet werden und ist daher zu vermeiden, es sei denn, es handelt sich um R-Software. R-Software transformiert fachliche Objekte in externe Repräsentationen und R wieder zurück. Beispiele für externe Repräsentationen sind Zeilen einer Datenbank-Tabelle, ein Bildschirmformat oder XML. R-Software kann häufig aus Metainformationen generiert werden. Diese fünf Kategorien formalisieren die Trennung der Zuständigkeiten nur auf der obersten Ebene. Selbstverständlich sollte sich jede T-Komponente nur mit einer technischen API befassen und nicht gleichzeitig mit zwei oder drei; jede A-Komponente sollte nur ein Anwendungsthema bearbeiten. 0 Kasten 1: Software-Blutgruppen Anfrage in das zugehörige serverseitige Formular (ActionForm) übertragen. Optional werden die Benutzereingaben validiert, sofern man die validate-Methode der ActionForm entsprechend implementiert. Die anwendungsspezifische Beschreibung der Aktionssteuerung erfolgt in der Konfigurationsdatei struts-config.xml. Hier wird in XML beschrieben, welche Aktion für welche URI ausgeführt werden soll und gegebenenfalls welches Formular serverseitig für die Benutzereingaben verwendet wird. Sowohl für Aktionen als auch für Formulare stellt das Struts-Framework Basisklassen bereit. Jede Aktion liefert als Ergebnis ihrer perform-Methode einen ActionForward an die Aktionssteuerung zurück. Über diesen ActionForward führt die Aktionssteuerung den nächsten Verarbeitungsschritt aus. Die Aktion beschafft sich den passenden ActionForward über ein ActionMapping, das zu einem symbolischen Namen einen 3/2002 zugehörigen ActionForward liefert. Ein ActionForward kapselt den Pfad zu einer beliebigen Ressource, die wiederum eine Action sein kann. Verkettungen von Aktionen werden somit möglich. Dialogschicht Struts unterstützt zustandslose Anwendungen. Komplexe Anwendungen zeichnen sich jedoch gerade durch eine komfortable Benutzerführung und ein Dialoggedächtnis aus. Im Dialoggedächtnis werden bereits getätigte Benutzerinteraktionen und Dialogdaten verwaltet (vgl. [Kam01]). Somit kann die Anwendung zustandsabhängig auf Benutzereingaben reagieren. Dazu braucht man in der Architektur des Systems eine ausgeprägte Dialogschicht, wie sie in [Den91] beschrieben ist. Struts kennt keine Dialoge, sondern nur Aktionen. Diese sind zu fein-granular, um die Fachlichkeit eines Dialogs abzubilden. Sie sind also für die Modularisierung der Dialogschicht nicht geeignet. Stattdessen müssen dazu mehrere Aktionen gebündelt werden, die miteinander kooperieren. Diese Kooperation verlangt eine gemeinsame Datenhaltung. Die Daten in den Aktionen zu halten (z. B. als MemberVariablen), ist deshalb nicht möglich, weil Aktionen pro Anwendung nur einmal instanziiert werden und keine exklusiven Ressourcen einer Sitzung darstellen. Sie müssen thread-sicher programmiert werden (vgl. [Str02], [Dav99], [Pel99]). Daher wird zum Datenaustausch zwischen Aktionen meist die HttpSession benutzt, in deren Attributen sitzungsbezogene Daten abgelegt werden können. Damit führt man allerdings sitzungsglobale Variablen ein (die Problematik globaler Variablen wurde bereits in [Wul73] hinreichend erläutert). Als Konsequenz droht schwer verständlicher und schwer wartbarer Code. Modelltransformation Zur Trennung von Präsentation und Dialog stellen sich einer Architektur für Abb. 1: Struts-Komponenten und Blutgruppen w w w. s i g s - d a t a c o m . d e s c h we r p u n k t ko m p l exe web-anwendungen mit „struts” Dialogbeschreibung mittels Interaktionsdiagrammen Interaktionsdiagramme (IAD) sind eine Variante endlicher Automaten. Ein IAD ist eine formale Spezifikation eines Dialogablaufs und kann zur Laufzeit von der Dialogsteuerung interpretiert werden, d.h. es ist automatisch ausführbar. Im Unterschied zu einem klassischen endlichen Automaten unterscheidet ein IAD zwischen Aktionen und Zuständen. In einem Zustand wartet das System auf eine Benutzeraktion bzw. ein Ereignis. Aktionen sind dagegen vom System ausführbare Funktionen. Zwischen zwei Zuständen kann es beliebig viele Aktionen geben. Der gesamte Weg von einem Zustand zum Folgezustand wird als Dialogschritt bezeichnet. In der Grafik wird beispielhaft ein trivialer Kundenanzeigedialog spezifiziert. Initialzustand des Dialoges ist die Kundensuche. Mit dem Benutzerereignis (virtuelle Taste) suche wird die Aktion suche Kunden ausgelöst. Abhängig von der Anzahl Treffer die zur Suchanfrage gefunden werden, verzweigt der Dialog zurück zur Kundensuche (0 Treffer), zur Aktion lese Kunden (1 Treffer) oder zum Zustand Kundenliste (1 Treffer). Im Zustand Kundenliste sind zwei Benutzerereignisse möglich: neue Suche oder auswählen eines Kunden. Der Zustand Kundendetails erlaubt lediglich eine neue Suche. Kasten 2: Interaktionsdiagramme Benutzungsschnittstellen drei Aufgaben: ■ Modelltransformation zwischen Dialog-Modell (Dialogdaten) und View-Modell (Präsentationsdaten) ■ Abbildung von Präsentations- auf Dialogereignis (Ereignisabstraktion) ■ Abbildung von Dialogzustand auf Präsentationssicht (View) Diese Aufgaben werden in der StrutsArchitektur nicht explizit abgebildet. Stattdessen muss sich jede Anwendung implizit selbst um diese Aspekte bemühen, was häufig in einer Vermischung von Aufgaben resultiert und versteckte Komplexität produziert. 28 29 Unterstützung für Multi-Channeling Immer häufiger sollen Anwendungen verschiedene Präsentationskanäle unterstützen (z. B. Web-Oberfläche und native Oberfläche). Um Multi-Channeling in der Architektur zu unterstützen, sollte man die Essenz der Benutzerinteraktionen abstrakt modellieren, ohne sich dabei auf die konkrete UI-API (z.B. Servlet/JSP, Swing) einzulassen. Dafür bieten sich z. B. Interaktionsdiagramme (IADs) bzw. UMLZustandsdiagramme an (siehe Kasten 2). Im Design wird diese abstrakte Beschreibung der Benutzerinteraktionen durch eine technikneutrale Dialogschicht abgebildet. Anwendungen, die naiv mit Struts gebaut werden, sind nicht multi-channel-fähig. Zustandsbehaftete Dialoge mit Struts Bisher wurden sowohl die Stärken als auch die Schwächen von Struts aufgezeigt. Im Folgenden stellen wir mit QUI-Web (Quasar User Interface für Web-Anwendungen) eine Erweiterung von Struts vor, welche die Konstruktion zustandsbehafteter Dialoge mit Struts ermöglicht, ohne dabei das Geheimnisprinzip durch sitzungsglobale Variablen zu verletzen. QUI-Web ist Teil der sd&m-Standardarchitektur QUASAR, vgl. [Sie00]. Was bietet QUI-Web? QUI-Web ist ein Toolkit für Web-Anwendungen, die auf JSP/Servlet-Technik basieren. Die Implementierung von QUI-Web verwendet Struts. Bei der Entwicklung wurde großer Wert darauf gelegt, ein schlankes und leicht wartbares Toolkit zu erstellen: Insgesamt besteht QUI-Web aus circa 40 Klassen und Interfaces, die von Java-Entwicklern in zwei Tagen leicht verstanden werden können. Als wesentlichen Mehrwert gegenüber Struts etabliert QUI-Web eine technikneutrale Dialogschicht, die von der JSP/Servlet-API und von Struts unabhängig ist. Die Dialogschicht ermöglicht es, zustandsabhängig auf eintreffende Benutzerereignisse (Dialogereignisse) zu reagieren. Im Dialog werden die Interaktionen des Benutzers mit der Anwendung abstrakt modelliert, ohne dabei auf die Spezifika der UI-API einzugehen. Als Modellvorstellung dafür dient das von Denert in [Den91] eingeführte Interaktionsdiagramm, eine Variante eines endlichen Zustandsautomaten (siehe Kasten 2). Ein Dialog besteht dabei im Wesentlichen aus Dialog-Aktionen und Zuständen. Die Kernidee ist, dass Dialogzustände von der Präsentationsschicht interpretiert und visualisiert werden. Diese Visualisierung ist channel-spezifisch. Hierfür bietet bietet QUI-Web Schnittstellen an. Die web-spezifischen Implementierungen dieser Schnittstellen bereiten die Präsentationsdaten in Form von JavaBeans auf und legen sie als Attribute der Anfrage ab. Die JSPs greifen beim Erzeugen der Ausgabe auf die Anfragen-Attribute zu und erhalten damit sowohl die benötigten Nutzdaten (z. B. für das Befüllen von Tabellen), als auch optional benötigte Metainformationen (z.B. Regeln für die clientseitige Validierung mit JavaScript). Aufwand und Nutzen QUI-Web erwartet vom Nutzer zusätzlich zur Struts-Konfiguration, dass er die an- w w w. o b j e k t s p e k t r u m . d e s c h we r p u n k t ko m p l exe web-anwendungen mit „struts” Abb. 2: Komponenten von QUI-Web und Blutgruppen. wendungsspezifischen Dialoge implementiert bzw. über IADs deklariert. Dialoge werden in der Initialisierungsphase der Anwendung beim Toolkit registriert. Außerdem implementiert der Nutzer die anwendungsspezifischen Modelltransformatoren (IDialogToView) und registriert sie beim Toolkit. Zusammenfassend stellt der Nutzer pro Anwendung die Klassen außerhalb der grau hinterlegten Komponenten in Abbildung 2 zur Verfügung. Die Komponenten selbst (QPresentation, QDialog) bekommt er zur Verfügung gestellt. Diese enthalten vorgedachte Interfaces und Implementierungen (0und T-Code), die in jeder Web-Anwendung wiederverwendet werden können. Komponenten von QUI-Web QUI-Web besteht aus den beiden Komponenten QPresentation und QDialog. QPresentation nutzt QDialog ausschließlich über die Schnittstellen IDialogManager und IDialogRead. QDialog macht keine Annahmen über QPresentation. Die Implementierung von QPresentation verwendet Struts. Genau genommen verwenden ausschließlich die Klassen QuiServlet, RequestListener und QuiForm Struts. Die Kernidee der Struts-Nutzung spiegelt sich in der Klasse RequestListener wider: der RequestListener ist eine StrutsAktion – die einzige Struts-Aktion, die in der Präsentation benötigt wird. Alle eingehenden HTTP-Anfragen werden vom zentralen QuiServlet (Subklasse von ActionServlet) entgegengenommen und an die Struts-Aktion RequestListener weitergeleitet. Dieser benutzt ein von der URI abhängiges, anwendungsspezifisches, serverseitiges Formular für die Verarbeitung der Eingabedaten. 3/2002 Die serverseitigen Formulare (QuiForm und anwendungsspezifische Subklassen davon) enthalten die Benutzereingaben einer Anfrage. Da die Abstraktion von Präsentationsereignis auf Dialogereignis im Allgemeinen datenabhängig ist, führen die Formulare diese durch. Die Methode zur Ereignisabstraktion ist genau der Mehrwert der QuiForm gegenüber der ActionForm. Der RequestListener verarbeitet eine Anfrage in folgenden Schritten: 1. Zunächst erfolgt die Synchronisation auf die HttpSession; damit werden konkurrierende Anfragen eines Benutzers sequenzialisiert. Anfragen unterschiedlicher Benutzer sind strukturell über die verschiedenen Instanzen von HttpSession entkoppelt und beeinflussen sich gegenseitig nicht. 2. Aus dem eingehenden Präsentationsereignis (HTTP-Request) wird das zugehörige Dialogereignis ermittelt; dazu wird das in der Konfiguration deklarierte, spezifisch fachliche Formular benutzt. 3. Das Dialogereignis wird dem DialogManager (DialogManager) zur Verarbeitung übergeben; hier erfolgt die Loslösung von der Technik und der Eintritt in die technikneutrale Dialogschicht. Der Dialog-Manager leitet das Dialogereignis an den dafür zuständigen Dialog weiter. Ein Dialog besitzt jeweils eine eigene Datenhaltung (DialogModel) und reagiert im Allgemeinen zustandsabhängig auf das eintreffende Dialogereignis mit der Ausführung einer Dialog-Aktion (DialogAction), in welcher der Aufruf der Anwendungsfälle des Anwendungskerns erfolgt. 4. Ist die Dialogschicht fertig mit der Verarbeitung des Dialogereignisses, wird der ViewManager damit beauftragt, die Präsentationsdaten (ViewModels) zu ermitteln. Dazu ist für den sichtbaren Dialog ein Modelltransformator (DialogToView) registriert, den der ViewManager benutzt. DialogToView interpretiert den Zustand des Dialogs, transformiert das Dialog-Modell in die aktuell für die Präsentation benötigten ViewModelle (JavaBeans) und fügt diese der HTTP-Anfrage hinzu. 5. Der RequestListener leitet die Anfrage an eine in der Konfiguration festgelegte Layout-JSP weiter: Diese stellt die Rahmenseite der Ausgabe dar; sie definiert das Layout und inkludiert die gerade benötigten Views. Die konkret zu inkludierenden JSPs sind ebenfalls in einem View-Modell hinterlegt (vgl. [Gea00]). Die Schnittstellen der wichtigsten Komponenten sind in Listing 1 dargestellt. Mehrwert für den Nutzer Gezähmtes Struts Ein Mehrwert von QUI-Web liegt im Nutzungskonzept der Struts-Aktionen. Statt die Dialoglogik und die Anwendungsfallaufrufe in den StrutsAktionen zu implementieren (AT-Software), verwendet QUI-Web genau eine Struts-Aktion als serverseitigen RequestListener, einer zustandslosen technischen Klasse (T-Software). Hier erfolgen die Loslösung von Struts und der Eintritt in die zustandsbehaftete, technikneutrale Dialogschicht. In der Methode perform des RequestListener erfolgt: ■ die Loslösung von der Servlet-API, ■ das Restaurieren und Suspendieren des Sitzungsgedächtnisses, ■ die Synchronisation paralleler Anfragen eines Benutzers, ■ die Abstraktion vom Präsentationsereignis zum Dialogereignis, ■ der Eintritt in die technikneutrale Dialogschicht, ■ das Erstellen der View-Modelle aus den Dialog-Modellen und ■ das Erzeugen der Ausgabeseite durch eine ActionForward. Abschirmung vor der UI-API Die Servlet/JSP-API ist die technische UIAPI der serverseitigen Präsentationsschicht. Sie wird in bestimmten Teilen der Präsentationsschicht verwendet: die JSPs und alle struts-behafteten Teile in der Architektur verwenden sie. w w w. s i g s - d a t a c o m . d e s c h we r p u n k t ko m p l exe web-anwendungen mit „struts” Interfaces für die Dialogschicht public interface IDialogEvent { public Symbol getEventId(); public Map getEventParams(); public Symbol getSourceDialogId(); public Symbol getTargetDialogId(); public int getDialogVersion(); } public interface IDialogManager { public void processDialogEvent(IDialogEvent event); public Symbol getVisibleDialog(); public IDialogRead getDialogRead(Symbol id); public void releaseDialogData(); } public interface IDialogManagerIntern { public void doDialogSwitch(Symbol sourceDialogId, Symbol targetDialogId, Map params); } public interface IDialog { public void processDialogEvent(IDialogEvent event); public RC leave(Map params); public void enter(Map params); public void releaseDialogData(); public IDialogRead getDialogRead(); } public interface IDialogAction { public Symbol execute(IDialog dialog, IDialogData data, Map params); } Interfaces für die Präsentationsschicht public interface IQuiForm { public IDialogEvent getDialogEvent(); } public interface IViewManager { public void putViewModels(IDialogManager dialogMgr, IRequest request); } public interface IDialogToView { public void putViewModels(IDialogManager dialogMgr, IRequest request); } Interfaces für das Sitzungsmanagement public interface IRequest { public ISessionMemory getSessionMemory(); public Object getViewModel(Symbol key); public void setViewModel(Symbol key, Object view); } public interface ISessionMemoryManager { public void initSessionMemoryManager(IQuiFactory quiFactory, Map params); public ISessionMemory getSessionMemory(Object session); public void suspendSessionMemory(Object session); } public interface ISessionMemory { public IDialogManager getDialogManager(); } Listing 1: Interfaces von QUI-Web Alle übrigen Komponenten werden von der UI-API nicht infiziert. Vorraussetzung dafür ist die Abstraktion von der HttpSession und dem HttpServletRequest, die wir durch die beiden Interfaces ISessionMemory und IRequest erreichen. Beide Interfaces sind mit Implementierungen hinterlegt (T-Software). Technikneutrale Dialogschicht QPresentation nutzt QDialog über die beiden schmal gehaltenen Schnittstellen IDialogRead und IDialogManager. Die Kopplung zwischen Präsentation und 30 31 Dialog ist damit minimiert. Die Anwendung ist von der UI-API abgeschirmt. Da die gesamte Dialogschicht technikneutral ist, kann sie für verschiedene GUIChannels verwendet werden (MultiChanneling). Über diese Schicht können sowohl zustandslose als auch zustandsbehaftete Dialoge realisiert werden. Für zustandsbehaftete Dialoge bietet QUIWeb verschiedene Mechanismen zum transparenten Management von Sitzungsdaten, die weiter unten beschrieben werden. Dialog und IAD-Interpreter Für die Implementierung eines Dialogs stehen dem Nutzer von QUI-Web verschiedene Wege offen: Entweder implementiert er die Dialogschnittstellen (IDialog, IDialogRead) eigenständig oder er verwendet eine vorgefertigte IAD-Dialogimplementierung (0-Software). Im letzteren Fall wird der Dialogablauf über eine IADBeschreibung in XML deklariert und über einen IAD-Interpreter zur Laufzeit ausgeführt. Die Nutzung der IAD-Dialogimplementierung erfordert keine Implementierungsvererbung. QUI-Web verfolgt stringent den Toolkit-Ansatz und benutzt keine Vererbungsbeziehungen zwischen Toolkit und Toolkit-Nutzer (vgl. [Broy02]). Der Mehrwert des IAD-Verfahrens besteht darin, für jeden Dialog eine geschlossene Darstellung des Dialogablaufs zu besitzen. Dies erleichtert das Verständnis und die Wartbarkeit der Anwendung wesentlich. Zusammen mit der Beschreibung der Struts-Aktionssteuerung hat man damit die gesamte Dialogdynamik deklarativ beschrieben. Das IAD-Verfahren eignet sich für 80% der Dialoge. Für Sonderfälle bleibt dem Benutzer über die manuelle Dialogimplementierung der User-Exit erhalten. Die Koordination der verschiedenen Dialoge der Anwendung übernimmt der DialogManager. Diese 0Komponente koordiniert Dialogwechsel und führt Buch über den sichtbaren Dialog im Kontext einer Anfrage. Modelltransformation und Ereignisabstraktion Technische Präsentationsereignisse (HttpServletRequests) werden in der QuiForm auf technikneutrale Dialogereignisse abgebildet (Ereignisabstraktion). Die Regeln dazu werden von der Anwendung definiert und beim Toolkit registriert. Die Dialogschicht verarbeitet ausschließlich Dialogereignisse; damit bleibt sie technikneutral. In der QuiForm findet die Modelltransformation für die Dateneingabe statt: Präsentationsdaten werden auf Dialogdaten abgebildet. Die Modelltransformation für die Datenausgabe geschieht in den anwendungsspezifischen Implementierungen von IDialogToView. Hier werden abhängig vom aktuellen Dialogzustand die Daten des Dialogmodells extrahiert und in Präsentationsdaten konvertiert (JavaBeans). Zusätzlich zu den Nutzdaten wird im Präsentationsmodell auch Metainformation für den Aufbau der View-Hierarchie (vgl. w w w. o b j e k t s p e k t r u m . d e s c h we r p u n k t ko m p l exe web-anwendungen mit „struts” [Gea00]) und für clientseitige Validierung abgelegt. technischen Aspekt nicht kümmern, denn sie bekommt davon nichts mit. Sitzungsmanagement und -gedächtnis Zwei zentrale Aspekte des Sitzungsmanagements sind: Erkennen technischer Navigation Jede zustandsbehaftete Web-Anwendung muss auf technische Browser-Navigation (Back-Button, History Bookmarks, parallel geöffnete Browser-Fenster) semantisch korrekt reagieren. QUI-Web stellt als Basisfunktionalität einen einfachen Mechanismus zum Erkennen technischer Navigation auf Dialogebene bereit. Die Anwendung entscheidet, wie fachlich korrekt darauf zu reagieren ist. Dazu wird das Dialog-Modell eines Dialoges versioniert. Bei jedem Schreibzugriff wird die Versionsnummer erhöht. Die Dialogversion wird als verstecktes Feld in die JSP eingebaut und zum Client geschickt. Über diesen Versionszähler können Konflikte erkannt werden. Die Versionierung pro Dialog erlaubt es dem Benutzer, mehrere Dialoge parallel zu bearbeiten – in jeweils eigenen BrowserFenstern. ■ das Aufrechterhalten der logischen Verbindung über mehrere C/S-Interaktionen hinweg und ■ das Verwalten von sitzungsbezogenen Anwendungsdaten. Der erste Punkt wird vom ServletContainer auf Basis von Cookies/URLRewriting geleistet (vgl. [Dav99]). Über das Interface HttpSession bietet die Servlet-API auch die Möglichkeit zur Ablage von Sitzungsdaten. Nutzt man diesen Mechanismus naiv, so werden die Sitzungsdaten für die gesamte Sitzungsdauer im Hauptspeicher des ServletContainers gehalten. Serverlast und die Menge der anfallenden Sitzungsdaten in der Anwendung fordern hier einen Designabwägung zwischen Ressourcenverbrauch (Hauptspeicher) und Performanz (Zugriffszeit). Um zu verhindern, dass diese Designabwägung die Architektur dominiert, versteckt man die Entscheidung hinter einem geeigneten Interface und entscheidet an zentraler Stelle über die Implementierungsvariante. Die Idee ist einfach: Jeder HttpSession wird ein Sitzungsgedächtnis (ISessionMemory) zugeordnet. Diese Zuordnung wird vom SessionMemoryManager hergestellt und verwaltet. Die Methode suspendSessionMemory erlaubt unter anderem folgende Implementierungsvarianten: ■ Die Methode besitzt einen leeren Rumpf, d. h. das Sitzungsgedächtnis bleibt die gesamte Sitzungsdauer über im Hauptspeicher. ■ Das Sitzungsgedächtnis wird in eine Datei serialisiert oder in die Datenbank geschrieben. ■ Das Sitzungsgedächtnis wird in einen String serialisiert und als verstecktes Formularfeld zum Client ausgelagert. Der Aufruf von suspendMemory fügt sich an zentraler Stelle in die QUI-Architektur ein. Die Anwendung muss sich um diesen 3/2002 Zusammenfassung QUI-Web ist eine Erweiterung des StrutsFrameworks für komplexe WebAnwendungen. Bestehender Struts-Code wird dabei nicht verändert. QUI-Web bietet gegenüber Struts als Mehrwert: ■ ein Dialogkonzept, das auch zustandsbehaftete Dialoge ohne die Verletzung des Geheimnisprinzips ermöglicht, ■ die Trennung zwischen Technik (JSP/Servlet) und Anwendungslogik (Dialog) sowie ■ ein transparentes Sitzungsmanagement mit flexiblen Implementierungsvarianten. Neben den bereits vorgestellten Features – wie dem Erkennen von technischer Navigation und der effizienten Dialoggestaltung mit Hilfe von Interaktionsdiagrammen – bietet QUI-Web noch zusätzlich eine eigene Validierungskomponente für die Prüfung von Benutzereingaben und ein durchgängiges Konzept zur Fehlerbehandlung. Bei einer großen Anzahl von Dialogen (mehr als 40) bietet sich ein Generatoransatz an, um die notwendige Produkti- vität im Entwicklungsprozess zu erzielen. View, View-Modell und Modelltransformation lassen sich deklarativ beschreiben. Aus dieser Beschreibung werden die JSPs und Java-Klassen generiert. Dieser Generatoransatz hat sich in Projekten bei der Firma sd&m bewährt. Für QUI-Web existiert derzeit kein Generator. Dies stellt den nächsten Schritt in der Weiterentwicklung des Toolkits dar. ■ Literatur & Links [Bar02] Baracuda – Surveying the Landscape (siehe http://barracuda.enhydra. org/cvs_source/Barracuda/docs/landscape.html) [Brö99] P. Brössler, J. Siedersleben, Software Technik, Hanser, 1999 [Brow01] S. Brown, R. Burdick, Professional JSP, 2nd Ed., Wrox Press, 2001 [Broy02] M. Broy, J. Siedersleben, Objektorientierte Programmierung und Softwareentwicklung: Eine kritische Einschätzung, in: Informatik Spektrum, 25, S. 3-11, 2002 [Dav99] J. Davidson, D. Coward, Java Servlet Specification, v2.2, Sun Microsystems Press, 1999 [Den91] E. Denert, J. Siedersleben, Software Engineering, Springer, 1991 [Gea00] D. Geary, JSP Templates (siehe http://www.javaworld.com/javaworld/jw-092000/jw-0915-jspweb_p.html) [Kam01] C. Kamm, F. Reine, H. Wördehoff, Basisarchitektur E-Business, in: Tagungsband GI/OCG Jahrestagung 2001 (2), S. 683-690 [Kas00] N. Kassem et al, Designing Enterprise Applications with the Java 2 Platform, Enterprise Edition, Addison-Wesley, 2000 [Par72] D. Parnas, On the Criteria to be Used in Decomposing Systems into Modules, in: Com. of the ACM, 15(12), S. 10531058, 1972 [Pel99] E. Pelegri-Llopart, L. Cable, Java Server Pages Specification, Version 1.1, Sun Microsystems Press, 1999 [Sad00] C. Sadtler, F. Hilgenberg et al, Patterns for e-business: User-to-Business Patterns for Topology 1 and 2 using WebSphere Advanced Edition, IBM, 2000 [Sie00] J. Siedersleben, E. Denert, Wie baut man Informationssysteme. Überlegungen zur Standardarchitektur, in: Informatik Spektrum 23(4), S. 247-257 (2000) [Str02] Struts Online Manual (siehe http:// jakarta.apache.org/struts/) [Wul73] W. Wulf, M. Shaw, Global Variables Considered Harmful, in: SIGPLAN Notices, 8(2), S. 28-34, 1973 w w w. s i g s - d a t a c o m . d e