CTC Analytics Support Portal

Größe: px
Ab Seite anzeigen:

Download "CTC Analytics Support Portal"

Transkript

1 Ein Content Management System mit Jakarta Struts und Object/Relational Bridge von Patrick Scheuerer Betreuer: Prof. Dr. Jörg Preussig

2 Erstellt im Januar 2004 Gedruckt und gebunden von Druckzentrum Laufen AG

3 Management Summary Das angestrebte Ziel dieser Diplomarbeit war die Erarbeitung einer dynamischen Web Applikation zur teilweisen Automatisierung des Supportbereichs der Firma CTC Analytics AG. Das CTC Support Portal, so der Arebitstitel der Applikation, soll den Kunden der Firma die Möglichkeit bieten, schnell und zielorientiert die gewünschten Dokumente und Software Downloads ausfindig zu machen. Für die Mitarbeiter der Firma CTC bietet eine Administrationskonsole die Möglichkeit, den Inhalt des Support Portals mit möglichst wenig Aufwand zu warten und zu aktualisieren. Zu Beginn der Diplomarbeit wurden in Zusammenarbeit mit dem Auftraggeber die detaillierten Anforderungen an die Applikation erarbeitet. Die definierten Workflows und Sicherheitsaspekte wurden in Use-Cases ausgearbeitet, welche die Grundlage für das Software-Konzept und die Architektur der Applikation darstellten. In der anschliessenden Implementierungsphase wurde das Design in iterativen Schritten zu einem Prototypen ausgearbeitet. Das modulare Schichtendesign garantiert eine gute Wartbarkeit und einen hohen Grad an Wiederverwendbarkeit. So wird zum Beispiel die Datenquelle durch eine abstrahierende Datenzugriffsschicht komplett vom Rest der Applikation abgekapselt. Durch diese Abstraktion kann die Datenquelle jederzeit durch eine andere Technologie ersetzt werden. Bei dieser Diplomarbeit ist ein durchdachtes, modulares Design für eine Web Applikation entstanden, das eine gute Erweiterbarkeit, Wartbarkeit und eine hohe Widerverwendbarkeit garantieren. Der vorliegende Prototyp bietet eine solide Basis für die Entwicklung eines produktiv einsetzbaren Produktes. 3

4

5 Inhaltsverzeichnis CTC ANALYTICS SUPPORT PORTAL... 1 MANAGEMENT SUMMARY... 3 INHALTSVERZEICHNIS EINLEITUNG SOURCE CODE REFERENZEN DANKSAGUNGEN AUFTRAG UND ANFORDERUNGEN AUSGANGSSITUATION ZWECK DER ARBEIT ANFORDERUNGEN VORGEHENSWEISE HERAUSFORDERUNGEN IN DER WEB-ENTWICKLUNG MVC, MODEL 1 UND MODEL 2 ARCHITEKTUREN DAS MODEL-VIEW-CONTROLLER PATTERN MODEL MODEL JAVA WEB APPLICATION FRAMEWORKS IM VERGLEICH Struts Tapestry Turbine Maverick Barracuda ERGEBNIS DER EVALUATION ANATOMIE EINER STRUTS APPLIKATION BASISELEMENTE EINER STRUTS APPLIKATION Konfiguration des ActionServlets STRUTS ACTION KLASSEN DIE STRUTS MODELL-KOMPONENTEN DIE STRUTS PRÄSENTATIONS-KOMPONENTEN

6 6.4.1 HTML Tag Library Logic Tag Library Beans Tag Library Template Tag Library ALLGEMEINE ARCHITEKTURÜBERLEGUNGEN WIEDERVERWENDBARKEIT UND WARTBARKEIT ABSTRAKTION DAS WEB-FRONTEND MIT STRUTS STRUTS ACTION SEITEN-LAYOUT MIT TILES FORMULARE MIT STRUTS ERSTELLEN VON FORMULAREN VALIDIERUNG VON FORMULAREN Konfiguration von struts-config.xml Das Apache Validator Framework DIE GESCHÄFTSLOGIK DESIGNÜBERLEGUNGEN UND VORGEHENSWEISE GESCHÄFTSLOGIKMODELL Business Delegate Pattern Service Locator Pattern IMPLEMENTIERUNG DES BUSINESS DELEGATE PATTERN Exception Handling Vermeiden von Abhängigkeiten IMPLEMENTIERUNG DES SERVICE LOCATOR PATTERNS DATENZUGRIFFSSCHICHT DESIGNÜBERLEGUNGEN UND VORGEHENSWEISE DATENMODELL DATENZUGRIFFSMODELL Value Object Pattern Data Access Object Pattern IMPLEMENTIERUNG DES DATA ACCESS OBJECT PATTERNS IMPLEMENTIERUNG DES VALUE OBJECT PATTERNS OBJEKT-RELATIONALE ABBILDUNG JAKARTA OBJECT/RELATIONAL BRIDGE (OJB)

7 12.2 KONFIGURATION DER DATENQUELLE KONFIGURATION DER OBJEKT-RELATIONALEN ABBILDUNG ABBILDUNG VON AGGREGIERTEN OBJEKTEN VERERBUNG UND POLYMORPHISMUS SICHERHEITSFUNKTIONEN BENUTZER UND ROLLEN ROLLEN-BASIERTER ZUGRIFF AUF DOKUMENTE UND DOWNLOADS Servlet Filter Konifguration von Servlet Filtern UserFilter AdminFilter VERBESSERUNGEN UND ERWEITERUNGSMÖGLICHKEITEN EINSATZ EINES PROFESSIONELLE PRÄSENTATIONSFRAMEWORKS ZUSAMMENFASSUNG ÄHNLICHER FUNKTIONALITÄT DEKLARATIVES EXCEPTION HANDLING GLOSSAR BIBLIOGRAPHIE ANHANG A ANHANG B ANHANG C ANHANG D

8

9 1 Einleitung 1.1 Source Code Syntaxbegriffe der verwendeten Technologien (z.b Java Code und XML Elemente) werden durchgehend in monospace Schrift dargestellt. Ziffern die am Rande von Quelltextblöcken in Klammern aufgeführt sind, dienen als Referenzpunkte in der nachfolgenden Beschreibung. 1.2 Referenzen Referenzen zur Bibliographie werden im Text durch in eckige Klammern gefasste Stichworte dargestellt, so bezieht sich [Struts] zum Beispiel auf folgenden Eintrag der Bibliographie: [Struts] Apache Software Foundation, Struts, Ziffern in runden Klammern (3) beziehen sich auf Referenzpunkte der unmittelbar vorhergehenden Abbildung (Source Code oder Diagramme). Hochgestellte Ziffern ( 1 ) markieren Fussnoten, die jeweils am unteren Seitenrand erläutert werden. 1.3 Danksagungen Der Firma CTC Analytics AG möchte ich für die mir gebotene Möglichkeit danken, dises Projekt realisieren zu dürfen. Insbesondere den Herren Hansjörg Cueni, Heiner Scherrer und Max Altenbach gebührt mein besonderer Dank. Seitens der FHBB möchte ich meinem Betreuer, Herrn Prof. Dr. Jörg Preussig, für seinen Rat und seine Unterstützung danken. Zudem möchte ich Matthias Wessendorf (Struts Use List) und Robert Muir Coup (OJB Mailing List) für Ihre Hilfe bei der Lösung von Problemen danken. 9

10 2 Auftrag und Anforderungen 2.1 Ausgangssituation Die Firma CTC Analytics AG stellt Roboter für die automatische Preparation von chemischen Proben her. Die Produkte werden ausschliesslich über ein weltweites Netz von Distributoren verkauft. Auch der Support für die Endkunden wird von den Distributoren erbracht. Auf der Website der Firma haben für Distributoren tätige Service Techniker oder in Ausnahmefällen auch sehr versierte Benutzer, die Möglichkeit, technische Dokumente, Software Updates und Firmware für die Produkte herunterzuladen. Dieser Supportbereich der Website ist geschützt und kann nur mit einem gültigen Benutzernamen und Passwort erreicht werden. Im Moment sind Benutzername und Passwort für alle Benutzer identisch. Der grosse Nachteil des bestehenden Supportbereichs ist, dass er komplett statisch ist. Dies macht den Workflow für Updates der Website sehr umständlich. Immer, wenn eine neue Datei im Supportbereich bereitgestellt werden soll, muss diese Datei von einem CTC Mitarbeiter an die Webdesign Firma gesendet werden, welche die Website entwickelt hat. Diese Firma lädt die Datei auf den Webserver hoch, und auf der Supportseite einen neuen Link auf die Datei. Im Durschnitt dauert dieses Prozedere ein bis drei Tage. Vor einigen Monaten hat man sich bei CTC für den Einsatz von Macromedia Contribute entschieden. Mit Hilfe dieser Software können die Mitarbeiter die neuen Dateien selbst hochladen und verlinken, ohne Kenntnisse von HTML oder anderen Technologien haben zu müssen. Das Hochladen von neuen Dateien ist aber nur eine der Unzulänglichkeiten der bestehenden Lösung. Momentan besteht der Supportbereich aus einer einzigen langen HTML Seite, auf der die verschiedenen Dokumente, nach Kategorie sortiert, aufgelistet sind. Aufgrund der Länge dieser Seite stellt sich das Auffinden eines bestimmten Dokuments oder einer Datei bisweilen als ziemlich umständlich heraus. Des weiteren ist die Sortierung ebenfalls statisch. Es kann beispielsweise nicht eine Liste aller für ein bestimmtes Produktemodell relevanten Dokumente angezeigt werden. 10

11 Wie bereits erwähnt sind momentan alle Supportdokumente auf einer geschützten Seite verlinkt. Das bedeutet, das jemand entweder vollen Zugriff oder gar keinen Zugriff auf diese Dokumente hat. Die Firma fände es aber wünschenswert, gewisse Dokumente allen Besuchern zugänglich zu machen und andere Dokumente vor allgemeinem Zugriff zu schützen. Aus all diesen Gründen kam die Firma CTC Analytics zum Schluss, dass die bestehende Lösung den Anforderungen nicht mehr genügt. 2.2 Zweck der Arbeit Der Zweck der vorliegenden Arbeit war es, einen Prototypen einer dynamischen Web- Applikation zu entwickeln, der die erwähnten Unzulänglichkeiten behebt, und der Firma die gewünschte Funktionalität zur Verfügung stellt. Während gewisse Anforderungen von vornherein klar waren, sollte der Prototyp für andere Anforderungen eine fundierte Entscheidungsgrundlage bieten. In einigen Punkten war man sich zu Beginn noch klar, welche Funktionalität die Geschäftsprozesse am besten reflektieren würde. Durch die Entwicklung eines Prototypen erhoffte man sich tiefere Einsicht in das technisch machbare und in die Möglichkeiten, die eine dynamische Webapplikation für die Firma eröffnet. 2.3 Anforderungen In diesem Abschnitt werden die in Zusammenarbeit mit dem Auftraggeber erarbeiteten Anforderungen an die Applikation zusammenfassend beschrieben. Die detailliert ausgearbeiteten Use-Cases befinden sich in Anhang A. Die Anforderungen lassen sich in zwei Gruppen unterteilen: Anforderungen aus Endbenutzersicht und administrative Anforderungen, die nur von einem Administrator (einem Mitarbeiter der Firma CTC Analytics) ausgeführt werden können. Die Anforderungen mit einem ausgefüllten Punkt wurden als Kernanforderungen definiert, die anderen als Anforderungen, die zu einem späteren Zeitpunkt implementiert werden können. Zuerst wird auf die erste Gruppe eingegangen. Software Downloads Ein Benutzer kann auf der Support Site Software, Firmware, etc. herunterladen. Knowledge Base 11

12 Ein Benutzer kann in der Knowledge Base technische Dokumente zu seinem Produkt suchen. o Feedback Ein Benutzer hat die Möglichkeit, Feedback zu einem Dokument zu senden. o Sortierung Ein Benutzer muss die Dokumente nach verschiedenen Kriterien sortieren können. o Stichwortsuche Ein Benutzer muss Dokumente anhand von Stichworten suchen können. Die Anforderungen im administrativen Bereich sind: Dokument erstellen Ein Administrator muss über ein Formular neue Dokumente und Software Downloads erstellen können Dokumente editieren und löschen Ein Administrator muss Dokumente und Software Downloads editieren und löschen können. Änderungen sollen sofort aktiv sein und sich auf der Website wiederspiegeln. Neue Kategorien erstellen Ein Administrator muss mittels eines Formulars neue Kategorien erstellen können. Kategorien editieren und löschen Der Administrator muss Kategorien editieren und löschen können. Benutzer authentifizieren Ein Administrator muss Kunden, die sich für erweiterten Zugriff registriert haben, authentifizieren können. o Neue Benutzergruppe Ein Administrator muss eine neue Benutzergruppe erstellen können. Wie man sehen kann, liegen die Mehrheit der Kernanforderungen im administrativen Bereich. Der Grund dafür ist, dass die Firma CTC Analytics vor allem eine mögliche Arbeitserleichterung für ihre Support Mitarbeiter mit Hilfe eines Prototypen evaluieren wollte. 12

13 2.4 Vorgehensweise In einem ersten Schritt galt es, die nötigen Artefakte zu erarbeiten, die für die Entwicklung einer Applikation notwendig sind. Diese Artefakte wurden in enger Zusammenarbeit mit der Firma CTC Analytics ausgearbeitet. Sie stellten die Grundlage für das weitere Vorgehen dar und dienten während der Entwicklungsphase als Referenz. Folgende Artefakte wurden erarbeitet: Ein detailliertes Use-Case Modell In diesem Dokument wurden sämtliche identifizierten Use-Cases ausführlich dokumentiert. Software Requirements Specifications Dieses Dokument definiert sowohl die funktionalen wie auch die nicht-funktionalen Anforderungen an die Applikation. Glossar Das Glossar dient der Verständigung zwischen Auftraggeber und Entwickler. Es beschreibt häufig verwendete Begriffe aus der Problemdomäne. Projektplan Der Projektplan definiert das zeitliche Vorgehen. Er gibt eine Übersicht über die einzelnen Iterationen sowie über das Projekt als Ganzes. Alle diese Artefakte befinden sich im Anhang dieser Arbeit. 13

14 3 Herausforderungen in der Web-Entwicklung Bevor man mit der Entwicklung einer Web Applikation beginnt, muss man sich gewisser Tatsachen klar werden, welche die Webentwicklung grundlegend von herkömlicher Softwareentwicklung unterscheiden. Eine der bemerkenswertesten Fakten ist, dass das World Wide Web (WWW) eigentlich nie dazu gedacht war, die Basis für weltumspannende, allzeit verfügbare und hoch personaliserbare Applikationen zu bilden. Die Basis des WWW ist HTML und HTML ist statisch. Die Natur heutiger Webapplikationen erfordert aber eine hochgradige Dynamik. Es ist somit nicht verwunderlich, dass während dem letzten Jahrzent unzählige Entwickler versucht haben, die angeborenen Unzulänglichkeiten der ursprünglichen Webtechnologien (HTML und HTTP) durch neue Technologien und Frameworks zu überwinden. Die folgende Auflistung erwähnt einige der Faktoren, die es bei der Entwicklung einer modernen Webapplikation zu beachten gilt. Das Web ist zustandlos. Das HyperText Transfer Protocol (HTTP) ist ein reines Request/Response Protokoll. Nachdem die Anfrage eines Benutzers bearbeitet wurde, wird die Verbindung abgebrochen. Für einen Webserver besteht keine Möglichkeit, eine permanente Verbindung zu einem Client aufrecht zu erhalten. Die Möglichkeiten, die ein Browser zur Entwicklung einer grafischen Benutzerschnittstelle bietet, sind sehr beschränkt. Die zur Verfügung stehenden Kontrollelemente von HTML Formularen können nur mit Text umgehen und machen es oft schwierig, die geforderte Funktionalität zu implementieren. Web Applikation müssen hochgradig skalierbar sein. Es ist nicht ungewöhnlich, das eine moderne Web Applikationen mit tausenden von Benutzern gleichzeitig fertig werden muss. Web Applikationen müssen immer verfügbar sein. Die Möglichkeit, über Nacht eine neue Version der Software zu installieren gibt es nicht: das Web kennt keine Nacht! Ausserdem ist jede Minute down-time (Zeit in der die Website nicht erreichbar ist) ein Imageverlust für eine Firma. 14

15 Oft kommt es vor, dass für eine Web-basierte Applikation unterschiedlichste Unternehmensressourcen integriert werden müssen. Diese sind meistens in einem Netzwerk und auf heterogenen Plattformen verteilt. Diese unternehmenskritische Ressourcen vor Angriffen aus dem Web zu schützen ist oft keine leichte Aufgabe. In Gegensatz zu einer herkömmlich unternehmensinternen Applikation bietet eine Webapplikation eine viel grössere Angriffsfläche für böswillige Benutzer. Eine Web Applikation ist für jede Person mit einem Internetanschluss zugänglich. Die Zahl der potentiellen Angreifer ist somit um ein vielfaches höher als bei einer herkömmlichen Applikation. Die Login- und Authenthiserungsmechanismen einer Web Applikation müssen dieser Tatsache Rechnung tragen und entsprechend robust sein. Die Menge an Inhalten und die Komplexität der Navigation, die eine Web Applikation verwalten müssen, ist oftmals enorm. Es ist keine Seltenheit, dass eine Web Applikation tausende von Seiten anbietet, mit denen der Benutzer interagieren kann. Dazu kommt, dass viele Web Applikationen die selben Inhalte an unterschiedliche Benutzergruppen anpassen müssen (z.b. Internationaliserung). All diese Punkte gilt es bei der Entwicklung einer modernen Web Applikation zu beachten. Einige davon liegen nicht (oder nicht ausschliesslich) im Aufgabenbereich des Entwicklers. Die meisten jedoch, haben einen direkten Bezug zur Architektur einer Web Applikation. Diese Überlegungen sind auch bei der Entwicklung des CTC Support Portals in die Architektur miteinbezogen worden. 15

16 4 MVC, Model 1 und Model 2 Architekturen Die Trennung von Geschäftslogik und Darstellung ist ein Problem, das besonders bei Web- Applikationen verstärkt auftritt: Bei der Entwicklung von Web-Applikationen werden diese beiden Bereiche meist von unterschiedlichen Personen mit unterschiedlichen Fähigkeiten entwickelt. Software Ingenieure entwickeln die Geschäftslogik der Applikation während Web Designer sich um die Präsentation der Daten kümmern. Das Problem ist, das viele Software- Entwickler nicht unbedingt gute Designer sind und nicht viele Designer beherrschen Programmiersprachen wie z.b. Java. Schon in den frühen 80er Jahren war diese Problematik bekannt und mit Smalltalk wurde zum ersten Mal ein konkreter Lösungsvorschlag dafür gemacht: das Model-View-Controller Konzept. 4.1 Das Model-View-Controller Pattern Das Model-View-Controller (MVC) Entwurfsmuster beschreibt eine saubere Trennung von Objekten in eine von drei Kategorien. Modelle (Model) kümmern sich um die Datenhaltung, Ansichten (Views) stellen alle oder einen Teil der Daten dar und Kontrolleinheiten (Controller) kümmern sich um Ereignisse die entweder Modell oder Anzeige beeinflussen. Die folgende Abbildung stellt das Zusammenspiel der verschiedenen Teile grafisch dar: 16

17 Kontrolleinheit empfängt ein Ereignis Kontrolleinheit Kontrolleinheit ändert Modell oder Ansicht Ansicht Ansicht Ansicht holt Daten vom Modell Modell Modell aktualisiert Ansicht wenn Daten ändern. Abbildung 1: Model-View-Controller Pattern Ereignisse veranlassen die Kontrolleinheit typischerweise, das Modell, die Anzeige, oder beides zu ändern. Immer wenn die Kontrolleinheit die Daten oder die Eigenschaften des Modells ändert, werden alle davon abhängigen Ansichten automatisch aktualisiert. Ebenso holt sich die Anzeige Daten vom Modell um sich zu aktualisieren. Dies geschieht, wenn die Kontrolleinheit eine Ansicht ändert, indem sie z.b. eine Fläche aufdeckt die vorher versteckt war. Alle hier verglichenen Web Application Frameworks haben eine Gemeinsamkeit: Sie implementieren in der einen oder anderen Weise das Model-View-Controller (MVC) Entwurfsmuster. 4.2 Model 1 Die ersten JSP Spezifikationen präsentierten zwei verschiedene Vorgehensweiesn um Web Applikationen mit JSP Technologie zu erstellen. Diese beiden Vorgehensweisen waren die Model 1 und Model 2 Architekturen. 17

18 Die beiden Architekturen unterscheiden sich in verschiedenen Schlüsselbereichen. Der Hauptunterschied ist, wie und von welcher Komponente die Bearbeitung der Anfrage behandelt wird. Bei der Model 1 Architektur wird die komplette Bearbeitung einer Anfrage von einer JSP Seite erledigt Browser (View) JSP (Model) JavaBean DBMS XML Web Container EIS Abbildung 2: Model 1 Architektur 4.3 Model 2 Die Model 2 Architektur ist eine serverseitige Implementation des MVC Musters auf Basis von Servlets und JavaServer Pages. Hier wird die Verarbeitung von Anfragen auf Kontroll (Servlet)- und Anzeigekomponenten (JSPs) aufgeteilt. Der Begriff Model 2 tauchte erstmals im 0.92 Release der Servlet/JSP Spezifikationen auf. Er Beschrieb darin eine Architektur, in der Servlets und JSPs zusammen in der selben Applikation verwendet werden. Der Begriff verschwand zwar aus den späteren Versionen der Spezifikation, er hält sich jedoch hartnäckig in der Java Webentwickler-Gemeinschaft. Beim Model 2 behandeln Servlet den Datenzugriff und den Navigationsfluss, während JSPs sich um die Präsentation kümmern. Das Model 2 ermöglicht es Java-Ingenieuren und HTML-Entwicklern, sich ausschliesslich um ihre Teile der Arbeit zu kümmern. Eine Veränderung in einem Teil einer Model 2 Applikation bestimmt nicht automatisch Veränderungen in einem anderen Teil der Applikation. 18

19 1 (Controller) Legacy System Servlet Browser (View) JSP, XSLT 4 (Model) JavaBean XML DBMS Web Container EIS Abbildung 3: Model 2 Architektur Der Controller nimmt Anfragen von Benutzern entgegen (1). Anschliessend wird die Geschäftslogik ausgeführt indem Methoden von Modelkomponenten aufgerufen werden (2). Ist die Bearbeitung der Anfrage abgeschlossen, wird die Kontrolle an die Ansicht weitergeleitet (3), welche die Resultate anzeigt. Die Resultate liest die Ansicht aus den Modellkomponenten aus (4) und präsentiert diese dem Benutzer (5). 19

20 5 Java Web Application Frameworks im Vergleich Die Firma CTC Analytics hat mir bei der Wahl der verwendeten Technologien freie Hand gelassen. Trotzdem erachtete ich es als sinnvoll, als Teil der Vorbereitungsphase des Projekts einen Vergleich der auf dem Markt erhältlichen Java Frameworks für Web Applikationen anzustellen und die einzelnen Produkte zu evaluieren. In diesem Kapitel wird jedes der evaluierten Frameworks kurz beschrieben Struts Das Struts Framework [Struts] wurde von Craig McClanahan entwickelt und im Jahre 2000 der Apache Software Foundation gespendet. Struts ist ein Open Source Framework für die Entwicklung von Web-Applikationen. Den Kern des Frameworks bildet eine flexible Kontrollschicht, die auf Technologien wie Java Servlets, JavaBeans, ResourceBundles und XML basiert. Druch seine Architektuer legt Struts die Anwendung des Model2 Entwurfsmusters nahe. Es bietet seine eigene Kontroller Komponente und verwendet verschiedene Technologien für das Modell und die Anzeige. Das Struts Modell kann mit Standard- Datenzugriffstechnologien wie zum Beispiel JDBC und EJB interagieren, aber auch viele Produkte von Drittanbietern wie Hibernate, ibatis oder ObjectRelational Bridge werden unterstützt. Für die Anzeige verwendet Struts bevorzugterweise JavaServer Pages, inclusive JSTL und JSF. Es werden aber auch andere Präsentationstechnologien wie Velocity oder XSLT unterstützt Tapestry Tapestry [Tapestry] ist eine Alternative zu Skripting Umgebungen wie zum Beispiel JavaServer Pages oder Velocity. Tapestry geht einen Schritt weiter, indem es ein Komponenten Objekt-Modell ähnlich dem von traditionellen GUI Frameworks verwendet. 20

21 Dieser Ansatz hat den Vorteil eines sehr hohen Masses von Wiederverwendung innerhalb von und zwischen Projekten. In Tapestry sind alles wiederverwendbare Komponenten. Das erklärte Ziel des Projektes ist die Elimierung von möglichst viel Code in Web- Applikationen. In Tapestry ist fast aller Code mit Applikationsfunktionalität verbunden. Um dieses Ziel zu erreichen verwendet Tapestry zur Präsentation HTML (oder eine andere Beschreibungssprache), der Inhalt wird in Java definiert und die beiden Teile werden über eine XML Spezifikation zusammengebunden. Diese drei Teile bilden eine Java Web- Komponente (JWC), der logischen Einheit einer Tapestry Applikation. Eine Java Web-Komponente kann, wie jede Komponenten, instanziert, konfiguriert und zu neuen grösseren Komponenten aggregiert werden. So ist zum Beispiel ein Textfeld auf einer Webseite eine Instanz einer JWC. Ebenso die Webseite selbst. Sie ist ein Aggregat aus vielen verschiedenenen JWCs. Im Lieferumfang von Tapestry ist schon eine Library von JWCs enthalten Turbine Turbine [Turbine] ist ein Servlet-basiertes Framework zur Entwicklung von sicheren Web- Applikaitonen. Es ist ebenfalls Open Source und Teil des Apache Jakarta Projektes. Es ist hauptsächlich für die Entwicklung von serviceorientierten Applikationen gedacht. So sind zum Beispiel ein Sicherheitsmanagement System, ein Scheduling Service, ein in XML definiert Formular-Validierungsserver und ein XML-RPC Service für Web Services Funktionen die in Turbine enthalten sind. Teile des Frameworks können auch unabhängig vom Web-orientierten Teil von Turbine verwendet werden. Der Kern von Turbine ist absolute unabhängig von der verwendeten Präsentationstechnologie. Sowohl JavaServer Pages wie auch Velocity werden unterstüzt. Turbine erfüllt zwar den Sun Standard für JSPs, erklärt jedoch Velocity zu seiner favorisierten Technologie 21

22 5.1.4 Maverick Maverick [Maverick] ist ein minimalistisches Framework, das sich einzig und allein auf die Logik, die zur Implementation des MVC Musters nötig ist, konzentriert und die Wahl der zu verwendenden Präsentationstechnologie dem Entwickler überlasst. Das Ziel des Projekts ist die Kombination der besten Elemente von Struts, WebWork und Cocoon2. Ein nettes Feature von Maverick ist die Verwendung von Reflection auf JavaBeans im der Präsentationsschicht um eine DOM Schnittstelle zu erzeugen (die Entwickler nennen das to domify Java objects ). Vor allem bei der der Verwendung von XSLT als Templating Technologie erspart das dem Entwickler den Aufwand, XML Dateien zu generieren und zu parsen. XSLT kann direkt auf das Modell angewendet werden. Ein interessanter Punkt, den man bei anderen Projekten vergeblich sucht, ist die Multiplattformunterstützung von Maverick: es wurde bereits auf.net und PHP portiert Barracuda Das Barracuda Präsentationsframework [Maverick] ist ebenfalls eine Model 2 Architektur, ähnlich zu Struts. Es geht aber einen Schritt weiter indem es zusätzlich einen Benachrichtigungs-mechanismus für Ereignisse am Modell bereitstellt. Barracuda verwendet nicht strikte JSP, sondern hat eine Template Engine Komponente entwickelt, welche die Vorteile von höherer Flexiblität und besserer Erweiterbarkeit haben soll. Zur Trennung von Programmlogik und Darstellung verwendet das Framework die XMLC Technologie für die Erstellung von Benutzerschnittstellen.XMLC ist ein Java-basierter Compiler der entweder ein HTML oder ein XML Dokument verwendet, um daraus Template Objekte zu erstellen die über die standartisierte W3C DOM Schnittstellen manipulierbar sind. Diese Template Objekte können dazu verwendet werden, um zur Laufzeit dynamisch Inhalt in ein Dokument einzufügen. Der Nachteil vom XMLC ist, das man sich mit Komplexität der low-level DOM Schnittstellen herumquälen muss. Barracuda löst dieses Problem, indem vorgefertigte MVC (ähnlich denen von Java Swing) Komponenten angeboten werden, über welche sich die 22

23 DOM Strukturen manipulieren lassen ohne direkt mit den DOM Schnittstellen in Kontakt zu kommen. Der Nachteil dieses Frameworks ist seine Komplexität und die damit verbundene relativ steile Lernkurve. Die Verwendung von XMLC und die Tatsache, dass Java Klassen aus HTML oder XML erstellt werden kann zu Beginn verwirrend sein. 5.2 Ergebnis der Evaluation Obwohl alle hier vorgestellten Frameworks die ähnliche Funktionalität bieten, gibt es vor allem bei deren Verbreitung und Reife erhebliche Unterschiede. Ich habe mich für das Struts Framework entschieden, weil es das verbreitetste und am besten dokumentierte Framework ist. Struts wird bereits in vielen Applikationen produktiv eingesetzt. Auch ist für das Struts Framework bereits eine grosse Zahl von hochwertiger Dokumentation vorhanden (Bücher, Tutorials, Beispielapplikationen). Schlussendlich, wurde meine Wahl sicherlich auch etwas durch meine subjektiven Präferenzen für das Struts Frameworks beeinflusst. 23

24 6 Anatomie einer Struts Applikation Wie schon erwähnt wurde, implementieren sehr viele Web Applikations-Frameworks das Model-View-Controller Entwurfsmuster. Struts macht dabei keine Ausnahme. Im folgenden wird erläutert, wie das Struts Framework aufgebaut ist und welche Kom-ponenten welche Aufgaben bei der Implementierung des MVC Musters übernehmen. 6.1 Basiselemente einer Struts Applikation Bevor die einzelnen Komponenten im Detail besprochen werden, wollen wir uns kurz einen Gesamtüberblick über Struts verschaffen. Die folgende Abbildung zeigt, was bei einer Anfrage eines Klienten abläuft: Action Form Klasse Model (Action Klasse) Controller strutsconfig.xml 5 View 6 Abbildung 4: Struts Übersicht Die Ausgangslage bildet eine Webseite (1), diese kann entweder statisches HTML bestehen oder eine JavaServerPage sein. Diese Webseite enthält eine Vielzahl von Aktionen (Actions), über welche der Benutzer die Ausführung von bestimmten Funktionen einer Applikation anstossen kann. Diese Aktionen können durch das Anklicken eines Hyperlinks oder durch 24

25 das Abschicken eines Formulars ausgelöst werden. Alle Aktionen, die vom Struts Framework behandelt werden sollen, müssen sich an ein bestimmtes URL Muster (z.b. /do/*) oder an eine bestimmte Dateierweiterung halten (z.b *.do). Diese Muster werden vom Servletcontainer dazu verwendet, alle Aktionen auf das Struts ActionServlet abzubilden (Action Mapping). Das Struts ActionServlet agiert als Controller der Struts MVC Implementation. Es nimmt Benutzeranfragen entgegen (2) und bildet sie auf eine in der Datei struts-config.xml definierten Aktion ab. Diese Datei enthält alle von Struts benötigten Konfigurationsinformationen, um eine Benutzeranfrage bearbeiten zu können. Mittels eines <action> XML Tags werden dem ActionServlet eine Menge von notwendigen Informationen mitgeteilt: Die Action Klasse, welche die vom Benutzer angeforderte Action ausführt. Eine Action Klasse ist eine Struts Klasse, die vom Entwickler erweitert werden muss. Ihre primäre Aufgabe ist die Kapselung aller Logik, die notwendig ist, um die Anfrage eines Benutzers bearbeiten zu können. Eine ActionForm Klasse, die alle vom Benutzer übermittelten Formulardaten validiert. Sie muss ebenfalls vom Entwickler erweitert werden. Nicht jede Struts Action erfordert auche eine ActionForm Klasse. Ein ActionForm wird nur benötigt, wenn Daten, die von einem Benutzer gesendet wurden, validiert werden müssen. Zusätzlich wird auch von der Action Klasse ein ActionForm verwendet, um die gesendeten Daten des Benutzers auszulesen. Dazu muss ein ActionForm für jedes Formularfeld eine get() und eine set() Methode anbieten. Der Name der Ressource, an die der Benutzer weitergeleitet werden soll, nachdem seine Anfrage von der Action Klasse bearbeitet worden ist. Da eine Benutzeranfrage verschiedene Resultate erzeugen kann, kann ein Action Mapping mehrere Weiterleitungen (Forwards) enthalten. Der Pfad einer Weiterleitung wird durch ein <forward> Tag gekennzeichnet und wird vom Struts ActionServlet dazu verwendet, den Benutzer zu einer anderen JSP Seite oder zu einem anderen Action Mapping in der Datei struts-config.xml weiterzuleiten. 25

26 Wenn der Controller alle diese Informationen zur Behandlung einer Anfrage aus dem entsprechenden <action> Element eingelesen hat, kann er entsprechende Benutzeranfrage behandeln. Wenn das <action> Element auf die Übermittlung von Formulardaten hinweist, wird das ActionServlet die Anfrage an die definierte ActionForm Klasse weiterleiten (3). Eine ActionForm Klasse enthält eine validate() Methode. Diese Methode wird vom Entwickler überschrieben und enthält die gesamte Validierungslogik die auf vom Benutzer übermittelte Daten angewendet werden. Falls die Validerungslogik erfolgreich durchlaufen wird, leitet das ActionServlet die Benutzeranfrage zur Bearbeitung an die Action Klasse weiter. Sind die übermittelten Daten ungültig, werden alle aufgetretenen Fehler in einer Collection namens ActionErrors gesammelt und der Benutzer wird auf die Seite zurückgeschickt, von der die Daten gesendet wurden. Wenn die Daten erfolgreich vom ActionForm validiert wurden oder das <action-mapping> kein ActionForm validiert, werden die Daten vom ActionServlet an die im Action Mapping definierte Action Klasse weitergeleitet (4). In der Action Klasse muss die öffentliche Methode execute() (vor Struts 1.1 hiess diese Methode perform() und ist jetzt deprecated ) vom Entwickler überschrieben werden. In dieser Methode befindet sich die gesamte Kontroll- Logik, die zur Bearbeitung der Benutzeranfrage notwendig ist. Nachdem die Action Klasse mit der Bearbeitung der Anfrage fertig ist, teilt sie dem ActionServlet mit, wohin der Benutzer weitergeleitet werde soll. Sie tut dies, indem sie dem ActionServlet einen Schlüsselwert übergibt, anhand dessen ein im <action-mapping> definiertes <forward> Element aufgefunden wird. In den meisten Fällen wird der Benutzer an eine JSP Seite weitergeleitet, die das Resutltat seiner Anfrage darstellt (5). Die JSP Seite wandelt die vom Modell erhaltenen Daten in eine HTML Seite um, die dann zurück an den Benutzer geschickt wird (6). 26

27 6.1.1 Konfiguration des ActionServlets Jede Applikation, die das Struts Framework verwendet, muss so konfiguriert werden, dass sie vom Struts ActionServlet erkannt wird. Um dies zu erzielen, muss das ActionServlet in der Datei web.xml mittels zwei XML Tag-Elementen konfiguriert werden: Einem <servlet> Tag, das den Namen der entsprechenden Java Klasse definiert und alle benötigten Konfigurationsparameter enthält, die das Servlet benötigt, wenn es geladen wird. Einem <servlet-mapping> Tag, das festlegt, wie Benutzeranfragen auf das ActionServlet abgebildet werden. Das <servlet> Tag, welches das ActionServlet des Support Portals konfiguriert, wird nachfolgend gezeigt: <?xml version="1.0" encoding="iso "?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" " <web-app> <display-name>ctc Analytics Support Portal Application</display-name> <!-- Action Servlet Configuration --> <servlet> <servlet-name>action</servlet-name> (1) <servlet-class>org.apache.struts.action.actionservlet</servlet-class> (2) <init-param> <param-name>config</param-name> (3) <param-value>/web-inf/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>2</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>2</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> Das <servlet> Tag definiert alle von Struts benötigten Informationen, um das ActionServlet in der Support Portal Applikation zu verwenden. Das <servlet-name> Tag 27

28 versieht das Servlet mit einem Namen (1). Das <servlet-class> Tag gibt den voll qualifizierten Klassennamen des Struts ActionServlets an (2). Über das config Attribut wird Struts der Name der Konfigurationsdatei mitgeteilt (3). Dieser kann auch von struts-config.xml abweichen. Das Struts ActionServlet bietet vielseitige Konfigurationsmöglichkeiten. In der gezeigten Konfiguration werden nur einige der möglichen Initialisierungsparameter verwendet. Ist das <servlet> Element konfiguriert, muss dem Web Container mitgeteilt werden, wie Benutzeranfragen an das ActionServlet weitergereicht werden sollen. Es gibt zwei Möglichkeiten dies zu tun: URL Präfix Abbildung (URL Prefix Mapping) Abbildung anhand der Erweiterung (Extension Mapping) Beim URL Präfix Mapping untersucht der Servlet Container die eingehenden URLs und bildet sie auf ein Servlet ab. Das URL Mapping für die CTC Support Applikation sieht folgendermassen aus: <web-app>... <!-- Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> (4) <url-pattern>/execute/*</url-pattern> </servlet-mapping> </web-app> Dieses Mapping teilt dem Servlet Container mit, dass jede Anfrage die an die CTC Support Applikation geht und das URL Muster /execute/* hat, an das ActionServlet weitergeleitet werden soll. Zum Extension Mapping ist noch zu erwähnen, dass diese Variante im Zusammenhang mit Firewalls zu Problemen führen kann. Einige Firmen erlauben nur Erweiterung wie.htm,.html,.jsp oder.php. Alle Anderen (und somit auch *.do) werden geblockt. 28

29 6.2 Struts Action Klassen Alle Actions einer Struts Applikation werden zentral in einer Datei definiert. Diese Datei heisst struts-config.xml und muss im WEB-INF Verzeichnis der Applikation erstellt werden. Die struts-config.xml Datei hat ein Wurzel Element namens <struts-config> <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" " <struts-config>... </struts-config> Alle Actions einer Applikation werden im <action-mappings> Element deklariert. Des weiteren hat jede Action ihr eigenes <action> Element. Der folgende Code Ausschnitt zeigt eine typische Action Konfiguration: <action-mappings> <action path="/login" (1) type="ch.ctc.support.struts.security.loginaction" (2) name="loginform" (3) scope="request" (4) input="/pages/login.jsp"> (5) </action> </action-mappings> Ein <action> Element hat verschiedene Attribute die gesetzt werden können. Ich werde hier nicht auf alle eingehen sondern nur dir oben gezeigten besprechen. Der Pfad (1) definiert das Mapping aber auch den Namen einer Action. Bei jeder eingehenden Anfrage durchsucht das ActionServlet alle in struts-config.xml definierten Actions. Wenn ein Benutzer eine Anfrage an die Adresse schickt, findet das ActionServlet das oben gezeigte <action-mapping>, indem es nach dem path Attribut sucht. An dieser Stelle sollte noch erwähnt werden, dass das path Attribut immer mit einem Vorwärts-Slash (/) anfangen muss. Sonst wird die Action nicht vom ActionServlet gefunden. 29

30 Das Typ Attribut (2) definiert den vollqualifizierten Namen der Action Klasse. Wenn der Benutzer die oben genannte URL aufruft, wird das ActionServlet eine Klasse vom Typ ch.ctc.support.struts.security.loginaction instanzieren. Diese Klasse enthält die gesamt Logik die notwendig ist, um die Benutzeranfrage zu bearbeiten (in diesem Falle den Benutzer einzuloggen). Das name Attribut (3) definiert das mit der Action assoziierte ActionForm. Wenn schon ein ActionForm des spezifizierten Typs existiert, wird es von Struts wiederverwendet. Ansonsten wird ein neues Objekt instanziert. Details zur Funktionsweise derklasse ActionForm werden in Kapitel 9 beschrieben. Das scope Attribut (4) definiert, in welchem Gültigkeitsgebiet das ActionServlet nach dem ActionForm suchen soll. Mögliche Werte sind page, request, session, application. Wird dieses Attribut nicht spezifiziert, sucht Struts in allen diesen Gültigkeitsbereichen. Das input Attribut gibt an, von welcher JSP Seite das Formular abgeschickt worden ist. Diese Angabe ist nötig, um Struts mitzuteilen, auf welche Seite der Benutzer zurückgeschickt werden soll, falls Fehler bei der Formularvalidierung auftreten. Genaueres dazu ebenfalls in Kapitel 9. Ein <action> Tag kann ein oder mehrere <forward> Elemente beinhalten. Ein <forward> Tag dient dazu, dem ActionServlet mitzuteilen, wohin der Benutzer nach der Bearbeitung der Anfrage weitergeleitet werden soll. Es besteht aus zwei Attributen: name und path. Der Name wird benötigt, um die Weiterleitung in einer Action referenzieren zu können. Das Pfad Attribut enthält die relative URL, an die der Benutzer weitergeleitet werden soll. Der folgende Code Ausschnitt zeigt die <forward> Elemente für die LoginAction: <forward name="login.success" path="/execute/setuphome" redirect="false"/> <forward name="login.failed" path="/pages/loginfailed.jsp" redirect="false"/> Das Beispiel zeigt, dass für bestimmte Actions mehrer <forward> Elemente nötig sind. Je nachdem, wie das Resultat der Bearbeitung einer Anfrage aussieht, muss der Benutzer an 30

31 unterschiedliche Seiten weitergeleitet werden. Im Beispiel wird der Benutzer nach erfolgreicher Authentifizierung an die Action setuphome weitergeleitet. Falls die Authentifizierung fehlgeschlagen ist (z.b. weil der Benutzer ein falsches Passwort verwendet hat), wird er auf die Seite loginfailed.jsp weitergeleitet. In manchen Fällen kann es sein, dass dasselbe <forward> Element von verschieden Actions benutzt werden muss. Für diesen Fall bietet Struts die Möglichkeit, <global-forwards> zu definieren. Diese <forward> Element sind von jeder Action aus referenzierbar. Das folgende Beispiel zeigt ein solches Element: <global-forwards> <forward name="system.failure" path="/pages/systemerror.jsp" redirect="false"/> </global-forwards> Da in jeder Action ein Fehler auftreten kann, wird global ein <forward> auf eine Seite definiert, die dem Benutzer eine Fehlermeldung anzeigt. 6.3 Die Struts Modell-Komponenten Struts selbst befasst sich hauptsächlich mit der Präsentation und Navigation einer Webapplikation. Es wird keine eigene Funktionalität für Modell-Komponenten angeboten. Die naheliegenste Lösung, die auch von den Struts Entwicklern empfohlen wird, ist der Einsatz von JavaBeans Komponenten. Struts bietet eine Vielzahl von Möglichkeiten, die dem Entwickler erlauben direkt und auf unkomplizierte Weise mit JavaBeans zu interagieren. Trotzdem sollte das Modell einer Web Applikation wohlüberlegten Anforderungen genügen (siehe auch Kapitel 3 und 7). Wenn ActionForms (die auch nichts anderes als JavaBeans sind) direkt in die Geschäftslogikschicht weitergereicht werden, koppelt dies das Struts Framework an den Rest der Applikation. Will man zu einem späteren Zeitpunkt z.b. ein Java Swing Frontend für die selbe Applikation entwickeln, steht man vor einigen Problemen, da Swing keine Ahnung hat von ActionForms. Generell sollte darauf geachtet werden, dass die JavaBeans nichts davon mitbekommen, dass sie in einer Web Applikation eingesetzt werden. Sobald man in seinen JavaBeans eine javax.servlet.* Klasse importieren muss, stimmt etwas nicht und man sollte das Design der Applikation nochmals prüfen. In einer Struts 31

32 Anwendung ist es die Aufgabe einer Action, alle Informationen die an die Geschäftslogik weitergegeben werden müssen, aus dem HTTP Request zu extrahieren und über Setter Methoden an die Geschäftslogik Beans zu füttern. Es ist also sehr wichtig, ein sauberes und gut durchdachtes Design zu verwenden. Abhängigkeiten zwischen den verschiedenen Schichten einer Applikation sollten wo immer möglich vermieden werden. Abhängig von der Grösse und Komplexität einer Applikation, können die Geschäftslogik Beans mit herkömmlichen JavaBeans implementiert werden, die mit Zustands-Beans interagieren oder über JDBC auf eine Datenbank zugreifen. Für grössere Anwendungen werden an Stelle solcher Beans oftmals stateless and stateful Enterprise JavaBeans (EJB) verwendet 6.4 Die Struts Präsentations-Komponenten Die Präsentationskomponenten, die üblicherweise in einer Struts-Applikation zum Einsatz kommen, sind die folgenden Tag Libraries: HTML Tags Bean Tags Template Tags Logic Tags Damit diese Tag Libraries in Struts verwendet werden können, müssen sie zuerst in web.xml deklariert werden: <web-app>... <taglib> <taglib-uri>/tags/struts-bean</taglib-uri> <taglib-location>/web-inf/tlds/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-html</taglib-uri> <taglib-location>/web-inf/tlds/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-logic</taglib-uri> <taglib-location>/web-inf/tlds/struts-logic.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-template</taglib-uri> <taglib-location>/web-inf/tlds/struts-template.tld</taglib-location> 32

33 </taglib> </web-app> HTML Tag Library Diese Tag Library dient der möglichst einfachen Entwicklung von HTML-basierten Formularen und ermöglicht es dem Entwickler, JSP Seiten zu schreiben, die eng mit einem ActionForm integriert sind. Die HTML Tag Library kann dazu verwendet werden, Kontrollelemente von HTML Formularen zu generieren und Daten aus einer ActionForm Klasse in der Session des Benutzers zu speichern oder mit der Anfrage zu übermitteln (im HttpRequest Objekt). Ein weiterer Vorteil dieser Tag Library ist die Verminderung von Scriptlet Code in JSP Seiten Logic Tag Library Die Logic Tag Library bietet dem Entwickler die Möglichkeit, in einer JSP Seite konditionale und iterative Kontrolle zu verwenden, ohne Java Scriptlets schreiben zu müssen. Die Logic Tags können grob in drei Kategorien unterteilt werden: Tags zur Iterationskontrolle Tags für konditionale Logik Tags um den Benutzer auf eine andere Seite zu schicken Die erste Gruppe beinhalte lediglich das Tag <logic:iterate>. Dieses Tag ermöglicht es, über eine Collection Objekt zu iterieren, das im Kontext der JSP Seite gespeichert ist. Das <logic:iterate> Tag unterstützt die folgenden Implementationen einer Collection: Vector ArrayList Arrays von Objekten (Arrays mit primitiven Datentypen werden nicht unterstützt) Java Enumeration Objekete Java Iterator Objekte In Kapitel 8 werden konkrete Beispiele zur Verwendung des <logic:iterate> Tags gemacht. 33

34 Die Tags für konditionale Logik bieten die Möglichkeit zur Überprüfungen von Eigenschaften des Servlet Containers. Sie können die Anwesenheit eines Datenwertes in mehreren Typen überprüfen: Cookie HTTP Header HTTPServletReuqest Parameter JavaBean Eine Property einer JavaBean Das folgende Code Beispiel illustriert die Verwendung der <logic:present> und <logic:notpresent> Tags: <logic:present scope="session" name="user"> You are logged in as: <bean:write name="user" scope="session" property=" " /><br> </logic:present> <logic:notpresent scope="session" name="user"> Anonymous </logic:notpresent> Der Inhalt des <logic:present> Tags wir ausgeführt, falls die unter name spezifizierte JavaBean in unter scope definierten Gültigkeitsbereich gefunden werden kann. Im obigen Beispiel wird also nach einer JavaBean namens user gesucht die im Gültigkeitsbereich der Session gespeichert ist. Wird diese Bean gefunden, wird die Adresse des Benutzers ausgegeben. Bei <logic:notpresent> ist das Verhalten gerade umgekehrt: der Inhalt des Tags wird ausgeführt falls die spezifizierte Bean nicht gefunden werden kann. Es gibt noch diverse andere Tags in der Logic Tag Library. Eine komplette Übersicht findet man unter [Taglib, Logic] Beans Tag Library Eine gut gestaltete JSP Seite verwendet JavaBeans, um die Präsentationslogik und die Daten, die von ihr dargestellt werden, zu trennen. Die JSP Spezifikation definiert eine Anzahl <jsp> Tags, die dem Entwickler die Möglichkeit geben, den Inhalt eines JavaBeans zu manipulieren. 34

35 Die Struts Bean Tag Library bietet einiges mehr an Funktionalität als die Standard <jsp> Tags. Diese Funktionalität kann grob in zwei Gruppen aufgeteilt werden: Das Generieren von darstellbarem Inhalt aus Daten. Das Erstellen von neuen JavaBeans, um Daten, die aus Web Artefakten wie beispielsweise Cookies oder Werten im HTTP Header gewonnen werden, speichern zu können. Die häufigste Anwendung von Struts Bean Tags ist das Auslesen von Daten aus einem JavaBean und deren Darstellung. Zu diesem Zweck existieren zwei Tags: <bean:write> <bean:message> Das <bean:write> Tag liest einen Wert aus einem JavaBean aus und schreibt ihn in die darzustellende Webseite. Das folgenden Code Beispiel zeigt die Verwendung dieses Tags: <bean:write name="categoryform" scope="request" property="iddisplay" /> Um dasselbe Resultat mit einem Java Scriptlet zu erzielen wäre der folgende Code nötig: <% %> CategoryVO category = (CategoryVO pagecontext.getattribute("category"); if (category!= null) { out.write(category.getid()); } In Kapitel 8 werden detailliertere Beispiele zur Verwendung dieses Tags gemacht. Die zweite Methode, um Ausgabetext aus einer JavaBean zu generieren ist das <bean:message> Tag. Dieses Tag dient der Trennung von statischem Inhalt und der Seite, in der dieser angezeigt wird. Der gesamte statische Inhalt wird in einer Properties Datei unabhängig von der Applikation gespeichert. Diese Properties Datei besteht aus Namen- Wert Paaren, wobei jedes Stück Text, das ausgelagert werden soll, mit einem Schlüsselwert assoziiert wird. Das <bean:message> Tag verwendet diesen Schlüssel, um ein bestimmtes Textfragment in der Properties Datei zu finden. 35

36 Um dem ActionServlet den Namen einer solchen Properties Datei mitzuteilten, verwendet man den application Parameter in der Konfigurationsdatei web.xml. <servlet>... <init-param> <param-name>application</param-name> <param-value>applicationresources</param-value> </init-param> </servlet> Das folgende Tag liest den ausgelagerten Text für den entsprechenden Schlüssel aus der Properties Datei aus und fügt ihn in die Webseite ein: <bean:message key="admin.newdownload.form.namelabel"/> Der passende Eintrag in der Datei ApplicationResources.properties sieht folgendermassen aus: admin.newdocument.form.namelabel=name Falls das <bean:message> Tag den spezifizierten Schlüssel nicht in der Properties Datei finden kann, wird eine Laufzeit Exception generiert. Die Instanzierung von JavaBeans in JSP Seiten wird hier nicht eingehender behandelt. Die Gründe dafür sind einerseits, dass ich in meiner Arbeit keine solchen Tags verwendet habe, der zweite Grund ist, dass die Funktionalität der meisten Instanzierungs-Tags auch direkt in der Action Klasse mit Java Code erreicht werden kann. Übermässige Verwendung von Instanzierungs-Tags kann ausserdem zu unübersichtlichem Präsentationscode führen. Detaillierte Informationen zu den Bean Instanzierungs-Tags kann unter [Taglib, Bean, Creation] gefunden werden: Template Tag Library Ich werde an dieser Stelle nicht auf die Template Tag Library eingehen, weil ich sie in meiner Arbeit nicht verwendet habe. Stattdessen kam die Tiles Library zu Einsatz, welche demselben 36

37 Zweck dient (der Separatation von Layout und Inhalt), aber einiges umfangreicher ist als die Template Taglib. Tiles wird in Kapitel 8 eingehender besprochen. 37

38 7 Allgemeine Architekturüberlegungen 7.1 Wiederverwendbarkeit und Wartbarkeit Ein Punkt, dem gerade bei der Entwicklung von Web Applikationen grosse Beachtung geschenkt werden sollte, ist die Wiederverwendbarkeit von Geschäftslogikkomponenten. Ohne sauberes Design kann es schnell passieren, dass sich Geschäftslogik quer über die Applikation verstreut wiederfindet. Auch wird die Geschäftslogik oft zu eng an eine Web Applikation gekoppelt, was zu grossen Problemen in der Wartung führen kann. Um eine möglichst hohe Wiederverwendbarkeit zu erreichen, ist es von enormer Wichtigkeit, die Applikation in verschiedene Schichten zu unterteilen. Wird dies nicht gemacht, kann dies zum sogenannten Concern Slush 1 Antipattern führen. Dieses Antipattern tritt auf, wenn der Applikationscode nicht in Schichten unterteilt wird, sondern in einem Matsch von Präsentationslogik, Geschäfslogik und Datazugriffslogik vermischt wird. Dies macht den Code sehr zerbrechlich. Schon kleine Änderung an der Funktionalität können einen Welleneffekt durch die gesamte Applikation auslösen. Hat man die Applikation in Schichten zerlegt (in den meisten Fällen sind es deren drei: Präsentationslogik, Geschäfslogik und Datazugriffslogik), lauert schon die nächste Gefahr. Das sogenannt Tier Leakage 2 Antipattern. Dieses Antipattern tritt auf, wenn trotz der logischen Unterteilung in Schichten Kommunikation zwischen nicht aneinander grenzenden Schichten stattfindet. Das bedeutet zum Beispiel, dass die Präsentationslogik direkt Dienste in der Datenzugriffsschicht aufruft. Die folgende Abbildung illustriert dieses Problematik. 1 Concern Slush heisst auf deutsch soviel wie Zuständigkeits-Matsch 2 Tier Leakage heisst auf deutsch Undichte Schichten 38

39 Präsentationsschicht Präsentationsschicht Geschäftslogikschicht Geschäftslogikschicht Datenzugriffsschicht Datenzugriffsschicht Offene (durchlässige) Architektur Geschlossene Architektur Abbildung 5: Tier Leakage Antipattern Eine durchlässige Architektur kann durch verschiedene Gründe verursacht werden. Einige davon sind Schichtenabhängige Klassen werden zwischen den Schichten hin und her geschickt. Implementationsdetails in einer Schicht werden gegenüber anderen Schichten offengelegt. In einer geschlossenen Architektur hingegen darf eine Schicht nur mit den direkt angrenzenden Schichten darüber oder darunter kommunizieren. Die Implementation wird durch wohldefinierte Schnittstellen abstrahiert. 7.2 Abstraktion Bei den meisten Web Applikationen wird über ein Web Frontend auf Back-Office Datenquellen zugegriffen. Hier muss darauf geachtet werden, dass die Datenquellen hinter einer abstrahierenden Schnittstelle vor der Geschäftslogik verborgen wird. Somit kann sicher gestellt werden, dass bei einem Wechsel der Datenquelle (z.b. Wechsel von MySQL auf Oracle) nicht Änderungen an der ganzen Applikation durchgeführt werden müssen. 39

40 8 Das Web-Frontend mit Struts In den folgenden vier Kapiteln wird die Architekur des CTC Support Portals und deren Implementation exemplarisch anhand eines konkreten Use-Cases beschrieben. Ich habe den Use-Case Neues Dokument erstellen gewählt, da dieser Use-Case von allen bisher erwähnten Struts Features Gebrauch macht und durch sämtliche Schichten der Architektur verläuft. Der Einfachheit halber wird dieser Use-Case hier nochmals kurz beschrieben. Neues Dokument anlegen besteht aus folgenden Schritten: 1. Der Benutzer füllt ein HTML Formular mit allen nötigen Daten aus und klickt auf den Submit Button um die Daten zu übermitteln. 2. Die übermittelten Daten werden validiert. Falls Fehler auftreten wird der Benutzer zurück zum Eingabeformular geschickt. Dort wird dem Benutzer mittels Fehlermeldungen angezeigt, welche Felder die Validierungsregeln verletzt haben. Der Benutzer korrigiert die Daten und klickt erneut auf Submit 3. Wurden die übermittelten Daten erfolgreich validiert, wird dem Benutzer eine Vorschau angezeigt, bei der er nochmals alle Angaben auf ihre Richtigkeit überprüfen kann. a. Die Angabe sind in Ordnung und der Benutzer klickt den Create Button um das Dokument zu erstellen. b. Die Angaben enthalten Fehler und der Benutzer möchte Änderungen vornehmen. Er klickt auf den Edit Button und wird zurück zum Eingabeformular geschickt. 4. Der Benutzer erhält eine Bestätigung, dass das Dokument erfolgreich gespeichert wurde. In disem Kapitel wird detailliert auf die Implementierung der Präsentationsschicht dises Use- Cases eingegangen. Neben den im Kapitel 6 bereits erwähnten Struts Features wird hier auch auf das Tiles Layout Framework eingegangen. 40

41 8.1 Struts Action Oftmals sind für die Bearbeitung einer Action gewisse Vorarbeiten nötig. Im Falle unseres Use-Cases müssen zuerst gewisse Daten aus der Datenbank gelesen werden, die für das erstellen des Formulars benötigt werden. Da ein Dokument einer Kategorie, einer Rolle (die Rolle, die benötigt wird, um auf dieses Dokument zuzugreifen) und einem oder mehreren PAL Modellen zugeordnet werden muss, benötigen wir die vorhandenen Kategorien, Rollen und PAL Modelle. Im dieses Problem zu lösen, wird zuerst eine sogenannte SetupAction aufgerufen. In dieser SetupAction werden alle notwendigen Daten aus der Datenback geholt und im Request gespeichert. Sind alle Vorbereitungsarbeiten abgeschlossen, leitet die SetupAction den Benutzer zum Eingabeformular weiter. Die folgende Ausschnitt aus der Datei struts-config.xml zeigt die Definition der SetupAction: <action path="/admin/setupnewdocument" type="ch.ctc.support.struts.admin.newdocumentsetupaction" name="documentform" scope="session" validate="false"> <forward name="admin.newdocument.setup.success" path="/pages/newdocument.jsp"/> </action> Der folgenden Code zeigt die Implementation der NewDocumentSetupAction: public class NewDocumentSetupAction extends Action { (1) public ActionForward execute( (2) ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { Collection palmodels, categories, roles; (3) try { CategoryManagerBD catbd = new CategoryManagerBD(); (4) categories = catbd.getallcategories(); palmodels = catbd.getpalmodels(); (5) UserManagerBD userbd = new UserManagerBD(); (6) roles = userbd.getroles(); 41

42 } } request.setattribute("categories", categories); (7) request.setattribute("allpalmodels", palmodels); (8) request.setattribute("roles", roles); (9) } catch (ApplicationException e) { return (mapping.findforward("system.failure")); (10) } return (mapping.findforward("admin.newdocument.setup.success"));(11) Jede Action muss der abstrakten Klasse org.apache.struts.action.action (1) abgeleitet werden (oder von einer davon abgeleiteten Basisklasse, die in web.xml definiert wurde). Des Weiteren muss jede Action die abstrakte Methode execute() implementieren (2). Wir benötigen drei Collection Objekte (3) um die Resultate, die uns die Datenbank zurückliefert, zu speichern. Als nächstes wird ein CategoryManagerBD() Objekt erstellt. Diese Klasse implementiert das Business Delegate Pattern, auf das wir in Kapitel 10 genauer eingehen werden. Nun rufen wir auf unserem catbd Objekt die Methode getallcateogories() auf und speichern das Resultat in der Collection categories. Nach demselben Verfahren holen wir auch alle PAL Modelle (5) und alle Rollen (6) aus der Datenbank. Anschliessend werden die Collections im Request unter einem entsprechenden Namen gespeichert (7, 8, 9). Wenn beim Laden der Daten ein Fehler auftritt, wird die Exception behandelt, indem der Benutzer über den Forward system.failure auf eine Seite weitergeleitet wird (10), die eine Fehlermeldung anzeigt. Dieser Forward wurde bereits in Kapitel 6.2 beschrieben und ich werde daher an dieser Stelle nicht mehr weiter darauf eingehen. Falls keine Fehler auftreten wird der Benutzer nach der Bearbeitung der Action über den Forward admin.newdocument.setup.success auf die Seite /pages/newdocument.jsp weitergeleitet. 8.2 Seiten-Layout mit Tiles Templates werden schon lange von Web Entwicklern verwendet, um statischen Inhalt von dynamischem zu trennen. In vielen Fällen wird dieses Problem mit includes gelöst. Bei diesem Ansatz lagert man oft wiederverwendete Teile einer Seite (z.b Header, Footer und Menu) in separate Dateien aus. Diese Dateien werden dann über include Direktiven in allen 42

43 anderen Seiten eingefügt. Das Problem mit includes ist, dass der Inhalt immer noch mit dem Layout gemischt ist, wenn auch ein bisschen weniger. Wenn zum Beispiel auf einmal der Ort des Menus in den Seiten wechselt, muss immer noch in jeder einzelnen Seite das include Statement angepasst werde. Der include Ansatz ist also ein Schritt in die richtige Richtung, aber er ist immer noch weniger Effizient als ein Template-basierter Ansatz. Ein Template ist eine JSP Seite, die eine JSP Tag Library verwendet, um das Layout einer Seite zu beschreiben. Das Template agiert als Definition dafür, wie die Seiten einer Applikation aussehen, ohne den Inhalt dieser Seiten zu spezifizieren. Der Inhalt wird zur Laufzeit in das Template eingefügt. Das Tiles Framework macht die Verwendung von Templates sehr viel einfacher, indem es dem Entwickler eine einfache aber effektive Tag Library zur Verfügung stellt. Das Tiles Framework kann mit jeder JSP Applikation verwendet werden (also auch unabhängig von Struts). In den meisten Fällen verwendet ein Template System ein Template für das Layout der Seite und ein weiteres Template, in dem die einzufüllenden Komponenten definiert werden. In Tiles werden diese Layoutseiten Definitions genannt. Der erste Schritt beim Erstellen eines Layouts ist die Identifikation der einzelnen Layout- Komponenten. Im Falle des CTC Support Portals bestehen diese Komponenten aus einem Header, einem Footer, dem Menu und dem Inhalt (Body). Die folgende Abbildung stellt das Layout des Support Portals schematisch dar. Header Menu Body Footer Abbildung 6: Seitenlayout des Support Portals 43

44 Der folgende Code zeigt eine vereinfachte Version des CTC Support Portal Layouts: taglib uri="/tags/struts-tiles" prefix="tiles" %> <html:html> <head> <title> <tiles:getasstring name="title"/> - (1) <tiles:getasstring name="subtitle"/> (2) </title> </head> <body> <table> <tr> <td><tiles:insert attribute="header"/></td> (3) </tr> <tr> <td><tiles:insert attribute="navigation"/></td> (4) </tr> <tr> <td> <table> <tr> <td><tiles:insert attribute="navigation"/></td> </tr> </table> </td> <td></td> </tr> <tr> <td> <table> <tr> <td><tiles:getasstring name="heading"/></td> (5) </tr> <tr> </table> <table> <tr> <td><tiles:insert attribute="content"/></td> (6) </tr> </table> </td> </tr> <tr> <td><tiles:insert attribute="footer"/></td> (7) </tr> </table> </body> </html:html> 44

45 Für jede Layoutkomponente, die wir definiert haben, erstellen wir ein <tiles:insert> Tag. Dieses Tag indiziert, dass an dieser Stelle ein Tile (oder Template), dass durch den spezifizierten Namen identifiziert wird, eingebunden werden soll (3-7). Das <tiles:getasstring> Tag bedeuted, dass der Attributwert als ein Stringliteral zurückgegeben wird. Es wird also aus den Komponenten title und subtitle der Titel der Webseite gebildet. Was ist nun aber genau ein Tile 3? Technisch gesehen ist ein Tile eine rechteckige Fläche in einer JSP Seite. Tiles können rekursiv gebildet werden und als Baum dargestellt werden. Für das obige Beispiel würde dieser Baum etwa so aussehen: Seite Layout Header Menu Body Footer Abbildung 7: Baumstruktur eines Tiles Layouts Jeder Knoten in diesem Baum repräsentiert eine Fläche. Der Wurzelknoten ist gewöhnlich die Seite. Endknoten oder Blätter enthalten die Inhalte. Dazwischenliegende Knoten repräsentieren für gewöhnlich das Layout der Seite. Ein Layout Template definiert also wo seine Tiles plaziert werden sollen, nicht aber welche Tiles es benutzen soll. Wenn wir uns nun die JSP Seite ansehen, zu der uns die NewDocumentSetupAction weiterleitet, sollten wir nicht erstaunt sein dort überhaupt keinen Inhalt zu finden. 3 zu Deutsch Kachel oder Platte 45

46 taglib uri="/tags/struts-tiles" prefix="tiles" %> <tiles:insert page="/layouts/supportdefaultlayout.jsp" flush="true"> (1) <tiles:put name="title" value="ctc Analytics support portal" /> <tiles:put name="subtitle" value="create a new document" /> <tiles:put name="header" value="/tiles/header.jsp" /> (2) <tiles:put name="footer" value="/tiles/footer.jsp" /> <tiles:put name="content" value="/tiles/documentformcontent.jsp" /> <tiles:put name="navigation" value="/tiles/adminnavigation.jsp" /> <tiles:put name="heading" value="create a new document" /> (3) </tiles:insert> In dieser JSP Seite wird nun eben definiert, welche Inhalte das Layout an welcher Stelle einfügen soll. Dazu muss die Seite natürlich das zu verwendende Layout deklarieren (1). Wir sehen auch, dass ein Tile entweder aus einer weiteren JSP Seite (dem Inhalt) bestehen (4) kann oder aber aus einem Stringliteral (3). Wenn wir jetzt zum Beispiel den Header austauschen möchten, müssen wir genau eine Zeile Code ändern: <tiles:put name="header" value="/tiles/newheader.jsp" /> Im folgenden Code Listing befindet sich auch ein Beispiel, in dem für das Attribut content nicht ein Tile, sondern wieder ein Layout eingebunden wird. Auf der Seite knowledgebase.jsp wird für das Attribut content wieder eine JSP Seite eingebunden, wie bisher. <tiles:put name="content" value="/tiles/knowledgebasecontent.jsp" /> Wenn wir uns die spezifizierte Seite knowledgebasecontent.jsp jedoch ansehen, sehen wir, dass diese wiederum mit Hilfe eines anderen Layouts verschiedene Tiles zusammensetzt. <%@ taglib uri="/tags/struts-tiles" prefix="tiles" %> <tiles:insert page="/layouts/maincontent.jsp" flush="true"> <tiles:put name="intro" value="/tiles/knowledgebaseintro.jsp" /> <tiles:put name="search" value="/tiles/searchknowledgebase.jsp" /> <tiles:put name="main" value="/tiles/browsedocumentsbycategory.jsp" /> <tiles:put name="popular" value="/tiles/mostpopulardocuments.jsp" /> <tiles:put name="recent" value="/tiles/mostrecentdocuments.jsp" /> </tiles:insert> 46

47 Dieses Beispiel illustriert sehr schön, dass Tiles beliebig tiefe Verschachtelungen von Layoutelementen ermöglicht. Das macht Tiles zu einem sehr mächtigen Template Framework. Tiles bietet aber noch vieles mehr. Für detaillierte Informationen siehe [Tiles]. 47

48 9 Formulare mit Struts Zwei der häufigsten Methoden, um HTML Formulare zu validieren, sind die Verwendung von JavaScript in den HTML- oder JSP-Seiten die das Formular enthalten, sowie das Vermischen von Validierungslogik mit der Geschäftslogik auf der Serverseite. Diese Inkonsistenz hat oftmals negative Konsequenzen: Die Validierungslogik ist durch die verschiedenen Schichten der Applikation verstreut. Dies erschwert die Wartung der Applikation beträchtlich. Validierungslogik wird auf verschiedenen Browsern unterschiedlich angewendet. JavaScript ist dafür bekannt (oder vielmehr berüchtigt), dass es obwohl standardisiert immer wieder zu grossen Kompatibilitätsproblemen auf verschiedenen Browsern kommt. Viel zu oft verwenden Entwickler aus Bequemlichkeit proprietäre Erweiterungen, die vom Standard abweichen. Durch die Verstreuung des Validierungscodes ist dessen Wiederverwendbarkeit stark eingeschränkt. Oftmals wird die älteste Form der Wiederverwendung copy & paste angewendet. Glücklicherweise bietet Struts eine reiche Auswahl von Diensten um Formulardaten zu erstellen und zu verwalten. Diese Dienste ermöglichen es dem Entwickler, die Validierung von Formularen in einer konsistenten Weise durchzuführen. Ein grosser Teil der Logik, die normalerweise notwendig ist, um Fehler abzufangen und diese dem Benutzer anzuzeigen, wird vom Struts Framework übernommen. 9.1 Erstellen von Formularen Um mit Struts HTML Formulare zu erstellen werden die folgenden Komponenten benötigt: Eine Struts ActionForm Klasse wird dazu benötigt, die gesammelten Daten zu speichern und diese zu validieren. Diese Klasse bietet eine einfach zu verwendende Verpackung. Der Entwickler muss die Daten nicht mehr selbsständig aus dem HttpServletRequest auslesen. 48

49 Eine Struts Action Klasse wird dazu benötigt die Benutzeranfrage zu bearbeiten. Alle nötige Geschäftslogik wird hier ausgeführt und ebenso das Einfügen, Aktualisieren oder Löschen von Datensätzen in der Datenbank. Eine JSP Seite, welche mit Hilfe der Struts HTML Tag Library die einzelnen Elemente des Formulars darstellt. Einmal mehr ist die Datei struts-config.xml die zentrale Stelle wo all diese Dinge zusammengeführt werden. Hier werden die von der Applikation verwendeten ActionForm Klassen definiert, von welchen Actions diese ActionForm Klassen verwendet werden und ob eine Action Klasse die übermittelten Daten validieren soll oder nicht. Jede Action Klasse, in der das Formular bearbeitet wird, muss in seinem <action> Tag den Namen des ActionForms angeben. Das folgende Diagram zeigt, was geschieht, wenn ein Benutzer Daten in einem Formular an eine Struts Applikation sendet. Benutzer In Session gespeichertes ActionForm ActionForm aus dem Cache Controller ActionServlet ActionForm.reset() ActionForm.validate() Webseite strutsconfig.xml Model Action. execute() Abbildung 8: Ablauf bei der Übermittlung einer Anfrage 49

50 Zuerst überprüft das ActionServlet die Datei struts-config.xml um festzustellen, ob ein ActionForm definiert wurde, das validiert werden muss. Wenn für die Action kein ActionForm definiert wurde, überprüft das ActionServlet einen internen Cache, um herauszufinden, ob ein ActionForm in der Session des Benutzers oder im Request gespeichert ist. Wenn ein ActionForm so konfiguriert wurde, dass es in der Benutzer-Session abgespeichert wird, überprüft das ActionServlet, ob bereits eine Instanz des ActionForms in der Session existiert. Ist dies der Fall, wird das ActionForm mit den im Request gespeicherten Daten gefüllt. Wenn es nicht existiert, wird vom ActionServlet ein neues ActionForm instanziert, mit den Daten aus dem Request gefüllt und in der Session gespeichert. Wenn das ActionForm für den Gültigkeitsbereich einer Anfrage konfiguriert wurde, durchsucht das ActionServlet wiederum seinen internen Cache nach einer Instanz des ActionForms. Findet es eine solche, wird die reset() Methode des ActionForms aufgerufen. Die reset() Methode versetzt das ActionForm in seinen Ausgangszustand (alle Werte werden auf null gesetzt) zurück, bevor es mit den Daten aus dem Request gefüllt wird. Die Methode wird nur aufgerufen, wenn sich das ActionForm im Request befindet. Wird es hingegen in der Session gespeichert, wird reset() nicht aufgerufen. Ob ein ActionForm im Request oder in der Session gespeichert wird, hängt von dessen Konfiguration im entsprechenden <action> Element ab. Mit den Konfiguration von ActionForms werden wir uns im nächsten Abschnitt befassen. Nachdem die reset() Methode ausgeführt wurde, wird als nächstes die validate() Methode aufgerufen. Die validate() Methode wendet die Validierungsregeln auf die vom Benutzer übermittelten Daten an. Wenn die Daten die Validierung erfolgreich durchlaufen, ruft das ActionServlet die execute() Methode der Action Klasse auf, die für die Bearbeitung der Benutzeranfrage zuständig ist. Wenn bei der Validierung Fehler auftreten, leitet das ActionServlet den Benutzer zurück zu Eingabeformular, von dem die Daten übermittelt wurden. Der Benutzer muss die Daten, welche die Validierungsregeln verletzt haben, korrigieren und erneut übermitteln. Wie Struts die Validierung genau durchführt, behandeln wir in nächsten Abschnitt. 50

51 9.2 Validierung von Formularen In unserem Use-Case Neues Dokument erstellen werden die Daten des documentforms an die Action NewDocumentPreviewAction geschickt. Die folgende Abbildung zeigt einen Screenshot des Formulars: Abbildung 9: New Document Formular Konfiguration von struts-config.xml Um eine ActionForm Klasse für die Validierung von Daten nutzen zu können, müssen zuerst einige Einstellungen in der Datei struts-config.xml vorgenommen werden. Mittels des <form-beans> Tags müssen alle in der Applikation verwendeten ActionForms definiert werden. 51

52 Im <action> Element, das die Benutzeranfrage bearbeitet, muss das Attribut validate auf true gesetzt werden. Im <form-beans> Element von struts-config.xml können ein oder mehrere <form-bean> Elemente enthalten sein. Jedes <form-bean> bezieht sich auf genau eine ActionForm Klasse in der Applikation. Für das documentform sieht das <form-beans> Element folgendermassen aus: <form-beans> <form-bean name="documentform" (1) type="org.apache.struts.validator.dynavalidatorform"> (2) </form-bean> </form-beans> <form-property name="name" (3) type="java.lang.string"/> (4) <form-property name="description" type="java.lang.string"/> <form-property name="version" type="java.lang.string"/> <form-property name="abstract" type="java.lang.string"/> <form-property name="categorydisplay" type="java.lang.string"/> <form-property name="palmodels" type="java.lang.string[]"/> <form-property name="keywords" type="java.lang.string"/> <form-property name="roledisplay" type="java.lang.string"/> <form-property name="file" type="org.apache.struts.upload.formfile"/> Struts bietet verschiede Implementationen von ActionForm an. Für alle diese Implementation müssen im <form-bean> Element die Attribute name und type spezifiziert werden. Das Attribut name (1) definiert den eindeutigen Namen des ActionForms. Dieser Name wird unter anderem dafür verwendet, dieses Formular Bean mit einer Action zu assoziieren. 52

53 Bei der hier gezeigten Variant eines ActionForms handelt es sich um ein DynaValidatorForm. Der grosse Vorteil dieser Implementation ist, dass der Entwickler das Bean nicht selbst implementieren muss. Die Definition erfolgt deklarativ in der Datei strutsconfig.xml. Für jedes Element des Formulars muss ein <form-property> Element definiert werden. Das Attribut name definiert den Namen der Property. Das Attribut type teilt dem ActionServlet mit, um was für einen Typen es sich bei dieser Property handelt. Wenn Struts nun auf das Formular Bean documentform zugreifen will, instanziert es dynamisch ein JavaBean mit einer get() und einer set() Methode für jede definierte <formproperty>. Auch die Methode reset() wird automatisch generiert. Struts löscht bei deren Aufruf einfach die Inhalte aller Properties. Die validate() Methode ist zwar vorhanden, ist aber leer und hat keinerlei Funktionalität. Der Grund dafür ist, dass die Validierung bei einem DynaValidatorForm nicht mehr von Struts selbst übernommen wird, sondern, wie der Name schon suggeriert, vom Apache Validator Framework [ASF, Validator]. ActionForms sind ein ziemlich umfangreiches Thema und ich habe es hier nur gestreift. Eine detaillierte Behandlung würde den Rahmen dieser Dokumentation aber bei weitem sprengen. Ausführliche Informationen zu ActionForms findet man unter [Struts, ActionForm] Das Apache Validator Framework Seit Version 1.1 bietet Struts Unterstützung für das Apache Commons Validator Framework. Dieses Framework ermöglicht es dem Entwickler, eigene Validierungsroutinen zu schreiben, die dann auf alle Formulare Beans anwendbar sind. Für detaillierte Informationen zum Validator Framework siehe [Validator]. Um das Validator Framework verwenden zu können, muss in der Datei struts-config.xml zuerst ein <plug-in> Element definiert werden. <plug-in classname="org.apache.struts.validator.validatorplugin"> (1) <set-property property="pathnames" (2) value="web-inf/validator-rules.xml,/web-inf/validator.xml" (3) /> </plug-in> 53

54 Das <plug-in> Element definiert den voll qualifizierten Namen der Plugin-Klasse (1). Das <set-property> Tag wird verwendet, um Plugin-spezifische Eigenschaften zu setzen. Im obigen Beispiel wird die Property pathnames angegeben (2), die dem Validator Framework mitteilt, wo es die benötigten Konfigurationsdateien validator-rules.xml und validator.xml findet (3). Die Datei validator-rules.xml enthält fixfertige Validierungsregeln die standardmässig mit dem Validator Framework mitgeliefert werden. Diese Regeln decken die am häufigst benötigten Validierungsregeln für HTML Formulare ab. Einige Beispiele dafür sind: Required maxlength minlength überprüft ob eine Feld ausgefüllt wurde überprüft die maximal zulässige Länge eines Feldes überprüft die minimal zulässige Länge eines Feldes überprüft ob der eingegebende Wert eine korrekt formatierte Adresse ist Die Datei validation.xml enthält zu Zuweisungen zu allen Formular Beans der Applikation, die das Validator Framework verwenden. Diese Datei bildet jedes Formularfeld auf die Validierungsregeln ab, die für dieses Feld durchgeführt werden sollen. Der folgende Code Ausschnitt zeigt die Validierungsregeln für das Feld Name des Formulars documentform. <form-validation> <formset> <form name="documentform"> (1) <field depends="required, maxlength" (2) property="name"> (3) <arg0 key="admin.newdocument.form.namelabel" name="required"/> (4) <msg key="errors.required" (5) name="required"/> (6) <msg key="errors.maxlength" name="maxlength"/> 54

55 </field> </form> </formset> </form-validation> <arg1 key="${var:maxlength}" (7) name="maxlength"/> (8) <var> <var-name>maxlength</var-name> (9) <var-value>50</var-value> </var> Das <form-validation> Tag ist das Wurzelelement der Datei validation.xml. Es repräsentiert eine Sammlung von Formularen für eine Applikation. Ein <formset> kann ein oder mehrere <form> Elemente enthalten. Ein <form> Element repräsentiert ein bestimmtes Formular Bean (1). Das Attribut name des <form> Tags muss den Namen des in strutsconfig.xml definierten Formular Beans enthalten. <form-bean name="documentform" type="org.apache.struts.validator.dynavalidatorform">... Jedes <form> Element enthält wiederum ein oder mehrere <field> Elemente. Ein <field> Element repräsentiert ein einzelnes Feld eines Formulars, das vom Validator Framework validiert werden soll. <field> hat zwei Attribute: property gibt den Namen des Feldes an das validiert werden soll (3). Dieser Name muss gleich sein wie der Name eines Feldes eines in struts-config.xml definierten <form-bean> Elementes. Dieses Attribut ist obligatorisch. depends listet alle Validierungsregeln auf, die auf Feld angewendet werden sollen (2). Die Überprüfungen finden in der Reihenfolge statt, in der sie aufgelistet sind. Dieses Attribut ist ebenfalls obligatorisch. Ein <field> kann ein oder mehrere <msg> Tags beinhalten. Dieses Tag wird von Validator dazu verwendet, um festzustellen, welche Nachricht dem Benutzer angezeigt wird (4), wenn eine Regel verletzt wird (5). Ein <msg> Element hat drei Attribute: name gibt an, mit welche Validierungsregel diese Nachricht assoziert ist (6). 55

56 key spezifiziert den Schlüsselwert für eine im Struts Resource Bundle gespeicherte Nachricht (5). In unserem Beispiel steht unter dem Schlüssel errors.required der folgende Wert: {0} is a required field. Please provide a value for {0} Das key Attribut ist obligatorisch. Das resource Attribut teilt dem Validator Framework mit, ob es das Struts Resource Bundle verwenden soll, um die Fehlermeldung dort zu suchen. Wird resource auf true gesetzt wird das Resource Bundel verwendet. Wenn es auf false gesetzt, wird das Resource Bundel nicht verwendet und der Wert der unter key spezifiziert wurde, wird als Stringliteral verwendet. Der Standardwert für resource ist true, deshalb wird dieses Attribut im Beispiel auch nicht aufgeführt. Ein <field> Attribut kann auch die Attribute <arg0>, <arg1>, <arg2>, <arg3> und <arg4> enthalten. Diese Tags werden dazu verwendet, Parameter an ein <msg> zu übergeben. Mit Hilfe dieser Attribute kann der Entwickler Parameter an eine im Resource Bundle gespeicherte Nachricht übergeben. In unserem Beispiel wird als erster Parameter der Name des Feldes übergeben wie es unter admin.newdocument.form.namelabel im Resource Bundle gespeichert ist (4). Das bedeuted, dass wann immer ein Fehler bei der Validierung auftritt, dieser Schlüssel verwendet wird um in ApplicationResources.properties den entsprechenden Wert zu suchen und damit eine String Substitution durchzuführen. Wenn also ein der Benutzer für das Formularfeld Name keinen Wert angibt, wird ihm folgende Fehlermeldung angezeigt: Name is a required field. Please provide a value for Name. Als zweiter Parameter wird die im <var> Element definierte Variable (9) an die maxlength Validierungsregel übergeben (7, 8). maxlength muss ja wissen wie lange die maximale Länge des Feldes sein darf. Das Validator Framework bietet noch viele weitere Möglichkeiten als die hier gezeigten. Unter anderem kann der Entwickler für spezifische Bedürfnisse neue Valierungsregeln 56

57 entwickeln. Diese müssen dann in der Datei validation-rules.xml deklariert werden, damit sie nutzbar sind. Detailliert Information zum Validator Framework findet man unter [Validator]. 57

58 10 Die Geschäftslogik Bis jetzt haben wir uns haupsächlich damit befasst, wie man mit Hilfe des Struts Framework eine Web Applikation entwickelt. Es wurden die nötigen Schritte beschrieben, um mit Struts eine Benutzeranfrage zu behandeln und die Komponenten, die dafür benötigt werden. Struts ist ein mächtiges Framework, das dem Entwickler viel Arbeit in der Präsentationsschicht abnimmt. Es entbindet ihn jedoch nicht davon, eine saubere Architektur für die Geschäftslogik, die von der Applikation verwendet wird, zu entwerfen. In den meisten Fällen ist die Geschäftslogik der am häufigsten wiederverwendete Code in einem Unternehmen. Die Geschäftslogik gehört nicht zu einer einzelnen Applikation, sondern beschreibt Arbeitsprozesse in einem Unternehmen. Es ist daher naheliegend, Geschäftskomponenten so zu entwickeln, dass sie in vielen Applikationen wiederverwendet werden können. Eben überall, wo ein bestimmter Arbeitsschritt auftritt. Bei der Entwicklung einer Struts Applikation sollte man diesen Gedanken immer im Hinterkopf haben. Koppelt man die Geschäftslogik zu eng an das Struts Framework, wird die Wiederverwendung von Geschäftskomponenten stark erschwert, wenn nicht sogar verunmöglicht. Im schlimmsten Fall ist die Geschäftslogik im verwendeten Framework eingeschlossen und ist ausserhalb des Frameworks nutzlos. In diesem Kapitel wird untersucht, wie diese Probleme durch die Verwendung von bewährten Entwurfsmustern verhindert werden können Designüberlegungen und Vorgehensweise Wir haben uns in Kapitel 7 schon mit den Antipattern Concern Slush und Tier Leakage befasst. Obwohl Struts durch seine Architektur dem Entwickler gewisse Richtlinien vorgibt, ist es trotzdem möglich, bei der Implementation von Action Klassen Fehler zu begehen, die sich später in diesen Antipattern manifestieren. Das Tier Leakage Antipattern tritt auf, wenn der Entwickler Implementationsdetails einer Applikationsschicht gegenüber anderen Schichten offenlegt. Ein Beispiel dafür ist, wenn die Präsentationslogik einer Applikation, was in unserem Fall eine JSP Seite ist, eine EJB erstellt und selbständig Geschäftslogik über diese EJB ausführt. Obwohl die Geschäftslogik in der EJB gekapselt und somit von der Präsentationsschicht getrennt ist, muss sich die JSP Seite 58

59 mit der Komplexität des Auffindens und Instanzierens einer EJB auseinandersetzten. Dies führt zu einer engen Abhängigkeit zwischen Präsentations- und Geschäftslogikschicht. Das Struts Framework bietet eine sehr saubere Trennung von Präsentationslogik und Geschäftslogik in einer Applikation. Die gesamte Präsentationslogik wird in JSP Seiten gekapselt und deren Implementation wird durch die Verwendung von Struts Tag Libraries stark vereinfacht. Die gesamt Geschäftslogik wird in den Action Klassen ausgeführt. Den JSP Seiten wird nie erlaubt, die Geschäftslogik direkt aufzurufen; das ist die Aufgabe des ActionServlets. Die Art und Weise, wie die Geschäftslogik implementiert wird, wird aber dem Entwickler überlassen. Es wäre durchaus möglich, die gesamt Geschäftslogik und den gesamten Datenzugriffscode in Struts Action Klassen zu verpacken. Dies kann aber, wie schon erwähnt, zu unerwünschten Effekten führen. Die Wiederverwendbarkeit wird eingeschränkt und die Wartung erschwert. Was können wir also tun um diese Probleme zu umgehen? Die Herausforderung liegt darin, die Geschäftslogik so zu implementieren, dass sie unabhängig vom Struts Framework bleibt. Die Action Klassen sollten lediglich als Behälter fungieren, über welchen die Geschäftslogik angedockt werden kann. Glücklicherweise bieten J2EE Design Patterns eine direkt anwendbare Lösung für dieses Problem Geschäftslogikmodell In diesem Abschnitt gehen wir auf die verwendeteten Design Patterns ein und besprechen, wie diese Entwurfsmuster uns dabei helfen können, die erwähnten Problem zu lösen. Wir beginnen die Erörterung mit dem Business Delegate Pattern Business Delegate Pattern In einer verteilten Anwendung kann das Auffinden von Daten und die Fehlerbehandlung für entfernte Geschäftskomponenten sehr komplex und ziemlich aufwändig sein. Wenn Applikationen Geschäftskomponenten direkt verwenden, muss der Applikationscode jedesmal angepasst werden, wenn sich die Schnittstelle einer Geschäftskomponente ändert. Dieses Problem kann gelöst werden, indem man eine vermittelnde Klasse, Business Delegate genannt, einführt. Diese Klasse entkoppelt die Geschäftskomponenten vom Code der sie 59

60 verwendet. Das Business Delegate Entwurfsmuster entschärft die Komplexität, die das Auffinden von Komponenten und die Fehlerbehandlung in verteilten Systemen mit sich bringt. Auch können die Schnittstellen von komplexen Geschäftskomponenten durch einfachere Schnittstellen verdeckt werden, um sie zum Beispiel in Ansichten darzustellen. Die folgende Abbildung zeigt, wie ein Business Delegate verwendet wird. Abbildung 10: Verwendung des Business Delegate Patterns Der Client greift über ein BusinessDelegate auf einen Geschäftsservice (BusinessService) zu. Falls nötig, instanziert die BusinessDelegate Klasse einen neuen Service oder sucht einen bestehenden Service Locator Pattern Das Auffinden und Erstellen eines Geschäftsservices ist in vielen Fällen recht aufwändig. Wenn dies direkt in der Geschäftslogik gemacht wird, kann dies zu viel redundantem Code führen. Das Service Locator Pattern mindert dieses repetitive Schreiben von Code. Ausserdem bietet es dem Entwickler die Möglichkeit, Implementationsdetails im Zusammenhang mit dem Auffinden und Instanzieren von Services zu verbergen. Eine Service Locator Klasse kann in einer vielzahl von Situationen eingesetzt werden. Einige davon sind: Beim Suchen von EJBHome Schnittstellen über JNDI Beim Suchen von JDBC Datenquellen über JNDI Das Aufsuchen einer Apache Axis Call classe um einen Web Service aufzurufen Das Laden eines Persistence Brokers / Managers für Objekt-relationale Mapping Tools 60

61 Ausserdem müssen solche Vorgänge oftmals optimiert werden, um Performance Engpässe zu vermeiden. Man kann sich leicht vorstellen, dass diese Aufgabe ziemlich nervenaufreibend wird, wenn jede Geschäftskomponente ihre Services selbsständig aufsucht und instanziert. Mit dem Service Locator Pattern hat man eine zentrale Stelle, an welcher solche Optimierungen durchgeführt werden können. Das folgende Diagramm, zeigt wie das Service Locator Pattern funktioniert: Abbildung 11: Verwendung des Service Locator Patterns Der Client benutzt die ServiceLocator Klasse (die meistens als Singleton implementiert wird) um an einen BusinessService zu gelangen, den er benötigt. Das hier gezeigte Beispiel zeigt noch die Verwendung eines InitialContexts oder einer ServiceFactory, um einen BusinessService aufzusuchen oder zu instanzieren. Diese Vorgehensweise wird vor allem bei der Verwendung von Enterprise JavaBean gewählt. Im Falle des CTC Support Portals, instanziert der ServiceLocator den BusinessService selbst Implementierung des Business Delegate Pattern Die Implementation des Business Delegate Patterns ist ziemlich einfach. Sie besteht darin, dass ein bereits existierender Service hinter einer einfachen Java Klasse versteckt wird. Jede 61

62 öffentliche Methode, die den Service anbietet, wird auf eine öffentliche Methode in der BusinessDelegate Klasse abgebildet. Das folgende Code Beispiel zeigt, wie in unserem Use-Case Neues Dokument erstellen, der Datenzugriff hinter eine BusinessDelegate Klasse namens DocumentManagerBD verborgen wird(die Details des Datenzugriffs werden im nächsten Kapitel besprochen). public class DocumentManagerBD { } public void adddocument(documentvo docvo) throws ApplicationException { try { DocumentDAO docdao = DocumentDAO.getInstance(); (1) docdao.insert(docvo); (2) } catch (DataAccessException e) { throw new ApplicationException( "DataAccessException in DocumentManagerBD.addDocument: " + e.tostring(), e); } } Die öffentliche Methode adddocument() macht im Prinzip nichts anderes, als ein neues Data Access Object zu instanzieren (1) und über dessen insert() Methode das als Parameter übergebende Dokument in die Datenbank einzufügen (2) Exception Handling Wenn sich beim Zugriff auf das Data Access Object ein Fehler ereignet, wird eine DataAccessException instanziert. Da wir dem Code, den unser Busienss Delegate verwendet, keine Implementierungsdetails über die Datenzugriffsschicht verraten wollen, verpacken wir die DataAccessException in eine generische ApplicationException. Diese muss nun vom aufrufenden Code behandelt werden. Das Business Delegate Pattern dient dazu, die Verwendung von Geschäftskomponenten zu vereinfachen und deren Implementierungsdetails zu verstecken. Die ApplicationException wird dazu verwendet, alle Exceptions, die in der Geschäftslogikschicht auftreten, zu einem einzigen, generischen Exceptiontyp zu normalisieren. 62

63 Vermeiden von Abhängigkeiten Ein weiterer wichtiger Punkt bei der Implementierung einers Business Delegates ist die Vermeidung von Abhängigkeiten zum aufrufenden Code. So könnten wir zum Beispiel unserer adddocument() Methode direkt ein ActionForm Objekt übergeben. Dieses Objekt beinhaltet eigentlich alle Daten, die wird benötigen. Tönt vernünftig, ist es aber nicht, denn wir haben gerade das Struts Framework an unsere Geschäftslogik gekoppelt! Da ActionForm eine Klasse des Struts Frameworks ist, wäre unsere Geschäftslogik jetzt nur noch von Struts Applikationen nutzbar. So schnell kann es gehen! Es ist also wichtig zu bemerken, dass einem Business Delegate nie Klassen übergeben werden, welche die Geschäftslogik an eine Front-End Technologie oder ein Framework binden können. Dieses Problem wird meistens mit sogenannten Transfer Objects gelöst, auf die wir in Kapitel 11 genauer eingehen werden Implementierung des Service Locator Patterns Im Falle des CTC Support Portals wird der Service Locator dazu verwendet, um an eine Instanz eines PersistenceBroker Objekts zu kommen. Dieses Objekt wird von den Data Access Objects dazu verwendet, Geschäftskomponenten durch die Verwendung eines objectrelationales Mappingtools persistent zu machen (mehr dazu im nächsten Kapitel). package ch.ctc.support.common; import org.apache.log4j.category; import org.apache.ojb.broker.pbfactoryexception; import org.apache.ojb.broker.persistencebroker; import org.apache.ojb.broker.persistencebrokerfactory; public class ServiceLocator { private static ServiceLocator _instance; (1) private PersistenceBroker broker = null; // Private Constructor for the ServiceLocator private ServiceLocator() throws ServiceLocatorException { (2) } public static synchronized ServiceLocator getinstance() (3) throws ServiceLocatorException { if (_instance == null) { try { _instance = new ServiceLocator(); } catch (Exception e) { 63

64 } throw new ServiceLocatorException( "ServiceLocatorException in ServiceLocator.getInstance(): ", e); } } return _instance; } public PersistenceBroker findbroker() (5) throws ServiceLocatorException { try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); } catch (PBFactoryException e) { e.printstacktrace(); throw new ServiceLocatorException( (6) "PBFactoryException error occurred while parsing the repository.xml file in ServiceLocator constructor", e); } return broker; } Die Klasse ServiceLocator wurde als Singleton implementiert. Das Singleton Design Pattern stellt sicher, dass nur eine einzige Instanz eines Objekts in einer Virtual Machine vorhanden ist. Durch Verwendung eines Singletons kann sichergestellt werden, dass in einer Applikation nicht Unmengen von Objekten erstellt werden, die einen sehr spezifischen Zweck erfüllen. Im Falle des ServiceLocators, ist der einzige Zweck der Klasse eine Instanz eines PersistenceBrokers zu erstellen (falls sie nicht schon exisitiert) und diese an das aufrufende Objekt zurückzugeben. Es ist nicht nötig, dass jedesmal, wenn dieser Service benötigt wird,auch eine neue Instanz eines ServiceLocators erstellt wird. Der ServiceLocator hat eine statische, private Instanz eines ServiceLocators (1). Damit keine Objekte vom Typ ServiceLocator instanziert werden können, wird der Konstruktor auf private gesetzt (2). Um auf die Instanz des ServiceLocators zugreifen zu können, wird die Methode getinstance() verwendet (3). Damit diese Methode auch in einer Applikation mit mehrerer Threads sicher ausgeführt werden kann, wird sie als synchronized markiert. Dies ist notwendig, denn wir wollen ja verhindern, dass mehrere Instanzen eines ServiceLocators erstellt werden. Wenn es aber mehreren Threads erlaubt ist, gleichzeitig getinstance() aufzurufen, kann genau das geschehen. Die Methode findbroker() macht nichts anderes, als ein PersistenceBroker Objekt zu instanzieren und dieses zurückzugeben. Alle bei der Instanzierung auftretenden Exceptions werden aufgefangen und eine neue ServiceLocatorException wird generiert. Dies dient wie 64

65 schon bei Business Delegate dazu, Implementationsdetails zu verbergen und die Geschäftslogik davor zu schützen, sich mit Details des Datenzugriffs auseinandersetzen zu müssen. 65

66 11 Datenzugriffsschicht In den letzten zwei Kapiteln haben wir uns mit der Präsentations- und Geschäftslogikschicht in einer Struts Applikation befasst. In diesem Kapitel wenden wir uns vom Struts Framework ab, und konzentrieren uns auf die Datenzugriffsschicht. Aber auch hier werden wir ein neues Framework kennenlernen: Object/relational Brigde (OJB) von der Apache Software Foundation. Ich habe mich aus zwei Gründen für die Verwendung dieses Frameworks entschieden: Einfachheit und Neugier. Einfachheit, weil mir OJB die Möglichkeit bietet, eine professionelle Persistenzschicht in meiner Applikation zu verwenden, ohne ein einziges SQL Statement schreiben zu müssem. Neugier, weil ich einfach daran interessiert war, die Technologie von objekt-relationalen Mapping Tools etwas genauer unter die Lupe zu nehmen Designüberlegungen und Vorgehensweise Bei der Enwicklung einer Datenzugriffsstrategie lauern eine Vielzahl von Stolpersteinen auf den Entwickler. Einige davon sind relativ einfach zu erkennen, andere wiederum sind gut verborgen und machen sich oft erst in der Wartungsphase einer Applikation bemerkbar. Dann ist es aber oftmals sehr schwierig, wenn nicht gar unmöglich, tiefgreifende Änderungen an der Datenzugriffsschicht vorzunehmen. Eine der wichtigsten Überlegung bei der Entwicklung der Datenzugriffsschicht ist die Unabhängigkeit von einer bestimmten Technologie oder Datenbank. Technologien ändern sich in der IT Industry so schnell, dass man es sich nicht erlauben kann, seine Applikation komplett von einer Technologie abhängig zu machen. Oftmals ändern sich die Geschäftsanforderungen an eine Anwendung, nachdem diese fertiggestellt wurde und eine enge Kopplung an bestimmte Technologien oder einen bestimmten Hersteller können es sehr schwierig machen, flexibel auf solche Änderungen zu reagieren. Eine Datenzugriffsschicht sollte es den Geschäftsdiensten einer Applikation ermöglichen, Daten zu konsumieren ohne wissen zu müssen, wo sich diese Daten befinden oder wie darauf zugegriffen wird. Ein paar Punkte sind dabei besonders zu beachten: Die Datenzugriffsschicht sollte eine klare Trennung der Datenzugriffslogik von Geschäftslogik und Präsentationslogik erlauben. So sollte eine Geschäftskomponente 66

67 nie direkt mit einem ResultSet oder mit einer SQLException zu tun haben. Der gesamte Datenzugriff sollte hinter einem Satz von Schnittstellen versteckt werden, welche von der Geschäftslogik verwendet werden müssen. Die Applikation sollte vollständig von jedem Wissen über die Datenbank-Plattform entkoppelt werden. Die Objekte in der Geschäftslogikschicht brauchen nicht zu wissen, dass sie auf eine relationale Datenbank, eine Objekt-basierte Datenbank oder eine XML Datenbank zugreifen. Die physiche Implementierung der Datenbank (also die Tabellen und deren Beziehungen) sollte komplett abstrahiert werden. So sollte eine Geschäftslogik-Klasse niemals wissen, dass ein Kunde über eine 1..n Beziehung mit einer Adresse verbunden ist. Die Applikationsentwicklung sollte so stark wie möglich vereinfacht werden. Ein Entwickler sollte sich so wenig wie möglich darum kümmern müssen, eine Verbindung zur Datenbank zu erhalten, einen SQL Befehl abzuschicken oder Transaktionen zu verwalten. Indem man allen Datenzugriffscode hinter ein paar Datenzugriffsdiensten versteckt, muss sich der Entwickler, der für die Geschäftslogik zustängig ist, keine Gedanken mehr darüber machen, wie oder wo seine Komponenten gespeichert werden. So kann zum Beispiel der Datenzugriffscode von einem darin erfahrenen Entwickler geschrieben werden. Alle anderen Entwickler benutzen die dafür vorgesehenen Dienste der Datenzugriffsschicht, um Daten zu laden oder zu speichern Datenmodell Die folgende Abbildung zeigt das Entity-Relationship Modell der Support Datenbank. Die meisten Tabellen und Beziehungen sind relativ selbsterklärend. Ich möchte an dieser Stelle lediglich auf die Beziehung zwischen t_document, t_download, t_keyword_supportitem, t_pal_model_supportitem und t_keyword und t_pal_model eingehen. Diese Tabellen und ihre Beziehungen sind später für die Diskussion des objekt-relationalen Mappings von besonderer Bedeutung. 67

68 Abbildung 12: Entity-Relationship Modell der Support Portal Datenbank Wie man auf der Abbildung sieht, haben t_document und t_download eine bereits zerlegte m:n Beziehung zu den Tabellen t_keyword und t_pal_model. Ausgedeutscht heisst das also, ein Dokument wird von 1..n Stichworten beschrieben und jedes Stichwort beschreibt 1..n Dokumente. Ebenso gehört ein Dokument zu 1..n PAL Modellen und jedes PAL Model kann 1..n mit ihm assoziierte Dokumente haben. Die selben Beziehungen bestehen für einen Software Download. Wie in den Verbindungstabellen t_pal_model_supportitem und t_keyword_supportitem bereits angedeutet wird, werden PAL Modelle und Stichwörter nicht direkt einem Dokument oder einem Software Downlaod zugeordnet, sondern einem generischen Support Item. Der Grund dafür ist, das Dokumente und Software Downloads beides Support Items sind. Wenn wir zum Beispiel alle Dokumente für ein bestimmtes PAL Model suchen, muss uns die Datenbank sowohl Dokumente wie auch Software Downloads zurückliefern. Wie sich dieses Problem relativ einfach lösen lässt besprechen wir in Abschnitt

69 11.3 Datenzugriffsmodell Die Datenzugriffsschicht des CTC Support Portals ist unter der Berücksichtigung eines Grundsatzes entwickelt worden: Die Geschäftslogik darf niemals direkt auf die Datenbank zugreifen. Um diesen Grundsatz durchzusetzten, werden zwei Design Patterns eingesetzt. Das Data Access Object (DAO) Pattern und das Value Object Pattern. Die folgende Abbildung stellt die Funktionsweise der Datenzugriffsschicht und die Rolle der erwähnten Patterns schematisch dar: Geschäftslogik Business Object Business Object Business Object Value Object Value Object Value Object Datenzugriff DAO DAO DAO Value Object Value Object Value Object Objekt -relationales Mapping Tool (OJB) Abbildung 13: Architektur der Datenzugriffsschicht Die Geschäftslogik darf nur über die Datenzugriffsschicht auf die Datenbank zugreifen. In der Datenzugriffsschicht bieten Data Access Objects über öffentliche Schnittstellen Zugriff auf die Datenbank an. Um die Kopplung der einzelnen Schichten aneinander zu minimieren, werden Value Objects (auch Transfer Object genannt) verwendet um die Daten von Schicht zu Schicht zu transportieren. 69

70 Value Object Pattern In einer Enterprise Applikation gibt es viele Geschäftskomponenten, die dem Benutzer über ihre Schnittstelle Services anbieten und teilweise Daten offenlegen. In manchen Fällen muss ein Klient mehrere Anfragen an eine Geschäftskomponenten richten, bis er alle nötigen Informationen erhalten hat. Da Enterprise Applikation in den meisten Fällen verteilter Natur sind, gehen diese Anfragen übers Netz. Man kann sich also vorstellen, dass Klienten, die sehr viele Anfragen an Geschäftskomponenten schicken, den Netzwerkverkehr stark belasten. Je mehr die Verwendung solcher entfernter Methoden ansteigt, umso schlechter wird die Performanz der Applikation. Aus diesem Grund ist es meist ineffizient, mehrere Methoden aufzurufen, welche die Werte der einzelnen Attribute zurückliefern. Man verwendet in diesem Fall ein Value Objekt (VO) um die Geschäftsdaten zu kapseln. Ein einziger Methodenaufruf wird verwendet um das VO zu erlangen. Wenn ein Klient eine Anfrage an eine Geschäftskomponente stellt, erstellt diese ein Value Objekt und füllt es mit seinen Attributwerten. Das VO wird anschliessend als Wert an den Klienten zurückgesendet. Durch die Verwendung eines VOs kann der Klient mit einem einzigen entfernten Methodenaufruf sämtliche für ihn relevanten Daten von einer Geschäftskomponente erlangen. Abbildung 14: Verwendung des Value Object Patterns 70

71 Abbildung 14 stellt das Konzept des Value Objects nochmals bildlich dar. Ein BusinessObject erstellt aus verschiedenen Datenquellen ein ValueObject, das es dann dem Client zur Verfügung stellt. Das folgenden Sequenzdiagramm illustriert den Ablauf bei der Verwendung eines Value Objects: Abbildung 15: Sequenzdiagramm zum Value Object Pattern Der Client ruft eine Methode auf einem BusinessObject auf (1). Das BusinessObject erstellt ein ValueObject (1.1) und gibt dieses an den Client zurück (1.2). Da es sich bei ValueObjects meistens um serialisierbare Objekte handelt, die in verschiedenen Adressräumen verwendet werden, muss der Client vor der Verwendung des ValueObjects zuerst eine lokale Kopie erstellen (1.2). Jetzt kann der Client lokal auf alle Daten des Value Objects zugreiffen (2, 3). 71

72 Data Access Object Pattern Code, der sich auf spezifische Funktionen einer Datenresource abstützt, koppelt Geschäftslogik und Datenzugriffslogik aneinander. Dies macht es schwierig, die Datenresource einer Applikation zu verändern oder auszuwechseln. Das Data Access Object (DAO) Pattern entkoppelt die Benutzerschnittstelle einer Datenresource von ihrem Datenzugriffsmechanismus und passt die spezifische Schnittstelle einer Datenresource an eine generische Benutzerschnittstelle an. Durch Verwendung des DAO Pattern lassen sich Veränderungen am Datenzugriffsmechanismus, unabhängig vom Code der die Resource verwendet, durchführen. Ein Datenzugriffsobjekt bietet Zugang zu einer Datenquelle, ohne deren Schnittstelle an die Geschäftslogik zu koppeln. Die Quelle kann dabei ein persistenter Speicher wie z.b. ein RDBMS sein, ein Web Service, ein LDAP Verzeichnis oder ein Geschäftsservice, auf den über CORBA IIOP zugegriffen wird. Die Geschäftskomponente die sich auf das DAO verlässt, verwendet die vereinfachte Schnittstelle, die das DAO seinen Benutzern anbietet. Die Implementationsdetails des Datenzugriffs werden somit komplett vor dem Benutzer versteckt. Weil die Schnittstelle, die vom DAO angeboten wird, nicht ändert, wenn die darunterliegende Datenquelle ändert, erlaubt dieses Entwurfsmuster die Anpassung an verschiedenste Speichersysteme, ohne dabei Benutzer- oder Geschäftskomponenten zu beeinflussen. Im Wesentlichen agiert das Datenzugriffsobjekt als Adapter zwischen Komponenten und einer Datenquelle. Abbildung 16: Verwendung des Data Access Object Patterns 72

73 Abbildung 16 stellt den Sachverhalt grafisch dar. Ein BusinessObject greift über ein DataAccessObject auf eine Datenquelle (DataSource) zu. Das DataAccessObjects gibt dem BusinessObject aber die aus der Datenquelle ausgelesenen Daten nicht direkt zurück, sondern verpackt sie in ein ValueObject. Dieses ValueObject kapselt die Daten und wird an das BusinessObject zurückgegeben. Abbildung 17 stellt die einzelnen Schritte bei der Verwendung eines Data Access Objects (DAO) am Beispiel einer Update Operation in einem Sequenzdiagramms dar. Abbildung 17: Sequenzdiagramm zum Data Access Object Pattern Das BusinessObject erstellt zuerst ein DAO (1). Anschliessend ruft es eine der Methoden des DAO auf (2). Das DAO holt sich die Daten aus der Datenquelle (2.1). Es erstellt ein 73

74 ValueObject (2.2), verpackt die Daten darin und sendet es zurück an das Business Object(2.3). Das Business Object kann nun die Daten (Properties) des ValueObjects verändern (3, 4). Wenn alle nötige Daten geändert sind, ruft das BusinessObject wieder eine Methode des DAOs auf und übergibt ihm das modifizierte ValueObject als Parameter (5). Das DAO entpackt die Daten aus dem ValueObject (5.1, 5.2) und führt die notwendigen Operationen an der Datenquelle durch (5.3) Implementierung des Data Access Object Patterns Alle DAOs in der Applikation implementieren eine einfache Schnittstelle namens DataAccessObject. Diese Schnittstelle garantiert, dass alle Datenzugriffsobjekte der Applikation die folgenden vier Methoden anbieten: findbypk() insert(); update(); delete(); Wenn alle DAOs alle eine bestimmte gemeinsame Funktionalität haben, könnte man das DataAccessObject auch als abstrakte Klasse implementieren. Dies ist aber in unserem Fall nicht gegeben. Der Code für die DataAccessObject Schnittstelle sieht folgendermassen aus: package ch.ctc.support.common; public interface DataAccessObject { public ValueObject findbypk(string primarykey) throws DataAccessException; public void insert(valueobject insertrecord) throws DataAccessException; public void update(valueobject updaterecord) throws DataAccessException; public void delete(valueobject deleterecord) throws DataAccessException; } 74

75 Als nächstes wollen wir wieder zurück zu unserem Use-Case Neues Dokument erstellen kommen. Der folgende Code Ausschnitt zeigt noch einmal die Methode adddocument() des DocumentManagerBD. public void adddocument(documentvo docvo) throws ApplicationException { try { DocumentDAO docdao = DocumentDAO.getInstance(); (1) docdao.insert(docvo); (2) } catch (DataAccessException e) { throw new ApplicationException( "DataAccessException Error in DocumentManagerBD.addDocument: " + e.tostring(), e); } } Um das neue Dokument persistent zu machen, holt sich der DocumentManagerBD in der Methode adddocument() zuerst eine Referenz auf das DocumentDAO Objekt (1). Alle DAOs wurden als Singleton implementiert, weil es nicht sinvoll wäre, die Instanzierung von Dutzenden von DAO Objekten zuzulassen. Als nächstes wird dem DAO über die Methode insert() ein DocumentVO ValueObject übergeben (2), das persistent gemacht werden soll. Im folgenden wollen wir uns die Implementation der insert() Methode des DocumentDAO genauer anschauen. public void insert(valueobject insertrecord) throws DataAccessException { PersistenceBroker broker = null; try { DocumentVO docvo = (DocumentVO) insertrecord; broker = ServiceLocator.getInstance().findBroker(); (1) broker.begintransaction(); (2) broker.store(docvo); (3) broker.committransaction(); (4) } catch (ServiceLocatorException e) { broker.aborttransaction(); (5) throw new DataAccessException( "ServiceLocatorException thrown in DocumentDAO.insert(): " + e.tostring(), e); } finally { if (broker!= null); (6) broker.close(); (7) } } Zuerst wird über den ServiceLocator eine Instanz eines PersistenceBroker Objects erlangt (1). Als nächstes müssen wir den Startpunkt für unsere Transaktion festlegen. Dies geschieht 75

76 über einen Aufruf der Methode begintransaction() (2). Jetzt kann das DocumentVO Objekt gespeichert werden (3). Wenn alles rund läuft, kann die Transaktion abgeschlossen werden (4). Falls beim Sichern des Objekts ein Fehler auftritt, muss die Transaktion rückgängig gemacht werden (5). Um die Verbindung zum PersistenceBroker garantiert zu schliessen, bevor wir die Methode wieder verlassen, wird in einem finally Block überprüft, ob die Verbindung noch offen ist (6). Ist dies der Fall, wird sie geschlossen (7) Implementierung des Value Object Patterns In der gesamten CTC Support Portal Applikation gibt es 7 Value Objects: CategoryVO DocumentVO DownloadVO PalModelVO KeywordVO RoleVO UserVO Alle diese Klassen erweitern die abstrakte Basisklasse ValueObject. import java.io.serializable; public abstract class ValueObject implements Serializable {......public ValueObject() {...} } Die Klasse ValueObject enthält keinerlei Funktionalität und wird ausschliesslich dazu verwendet, Objekte als ValueObjects zu markieren, indem sie diese Klasse erweitern. Man spricht hier von einer Markierungsschnittstelle. Da ValueObjects häufig zwischen verschiedenen virtuellen Maschienen hin und her transportiert werden, sollte die Basisklasse zumindest die Serializable Schnittstelle implementieren. Ausserdem wird die abstrakte Klasse ValueObject dazu verwendet, den DataAccessObjects generischen Typen als Parameter- und Rückgabetyp zu bieten. Indem wir einer DataAccessObject Schnittstelle nur ValueObjects übergeben, können wir sicherstellen, das jedes DAO eine Grundmenge an 76

77 CRUD Funktionalität bereitstellt. Es ist die Aufgabe jedes DAO, die ValueObjects in den Typen umzuwandeln, den es erwartet. Die einzelnen Implementationen der ValueObjects sind nichts anderes als simple JavaBeans. Jedes von ihnen hat eine Anzahl privater Attribute und für jedes dieser Attribute wird eine get() und eine set() Methode bereitgestellt. Wir wollen uns an dieser Stelle nur die Attribute des ValueObjects DocumentVO anschauen. public class DocumentVO extends ValueObject (1) implements SupportItemI { (2) } private Long _id; private String _name; private String _description; private String _version; private byte[] _abstract; private Date _creationdate; private Long _categoryid; private CategoryVO _category; private Collection _collectionofpalmodels; private String _keywords; private Collection _collectionofkeywords; private UserVO _author; private Long _authorid; private String _filepath; private Long _roleid; private RoleVO _role; DocumentVO erweitert die abstrakte Basisklasse ValueObject (1). Ausserdem implementiert die Klasse die Schnittstelle SupportItemI. Diese Schnittstelle definiert einen abstrakten Supportgegenstand. Dies kann ein technisches Dokument, ein Software Download oder etwas anderes sein. Momentan wird diese Schnittstelle nur von DocumentVO und DownloadVO implementiert. SupportItemI definiert eine handvoll Methoden, die von jedem Supportgegenstand implementiert werden müssen: public interface SupportItemI extends Serializable { public Long getid(); public void setid(long id); public String getname(); public void setname(string name); public String getdescription(); public void setdescription(string description); 77

78 } public String getversion(); public void setversion(string version); public Collection getcollectionofpalmodels(); public Date getcreationdate(); public void setcreationdate(date date); public CategoryVO getcategory(); public void setcategory(categoryvo category); public RoleVO getrole(); public void setrole(string role); public File getfile(); public void setfile(string file); public void setkeywords(string keywords); public void addtopalmodel(string palmodelid); Der Rest der Klasse DocumentVO wird nicht eingehender besprochen. Im Code Beispiel werden noch alle Attribute der Klasse aufgelistet. Zu diesen Attributen existieren in der vollständigen Implementation get() und set() Methoden. Einige dieser Methoden werden ja in der Schnittstelle SupportItemI gezeigt. 78

79 12 Objekt-relationale Abbildung Es existiert die Meinung 4, dass 40 60% der Zeit, die für die Entwicklung einer Applikation aufgebracht wird, mit dem Schreiben von Datenzugriffscode verbracht wird. Für Java Entwickler bedeutet dies in den meisten Fällen viel SQL und JDBC Code zu schreiben. Durch die Verwendung eines objekt-relationalen Mapping Tools kann der Aufwand für die Entwicklung der Datenzugriffsschicht drastisch reduziert werden. Solche Tools ermöglichen dem Entwickler, herkömmliche Java Objekte völlig transparent in eine Datenbank zu sichern. Die dafür nötigen SQL Anweisungen werden dynamisch vom Mapping Tool erzeugt Jakarta Object/Relational Bridge (OJB) OJB [OJB] ist eines der neueren Jakarta Projekte. Es ist ein vollfunktionales objektrelationales Mapping Tool. OJB basiert auf einer Mikrokernel Architektur: eine Gruppe von minimalen und sehr knappen gehaltenen APIs bieten die Kernfunktionalität an. Zusätzliche Funktionalität wird dann in Form weiterer APIs um diesen Kern herum aufgebaut. Abbildung 18 illustriert diese Architektur. Den Kern von OJB bildet die Persistence Broker API (PB). Diese Programmierschnittstelle bietet die grundlegenden Methoden für die Interaktion mit einer Datenquelle. Die PB API unterstützt nur die Interaktion mit relationalen Datenbanken. Sie verwendet dazu JDBC 1.0 und eine Teilmenge von SQL, um eine möglichst grosse Anzahl von verschiedenen Datenbanken unterstützen zu können. Das OJB Entwicklungsteam plant für zukünftige Versionen die Unterstützung neuerer JDBC Features und ausserdem Unterstützung für Object-, LDAP- und XML-basierte Datenbanken. Die Konfiguration der objekt-relationalen Abbildung mit OJB ist ein simpler Vorgang. Es müssen lediglich zwei Dateien angelegt und editiert werden: OJB.properties und repository.xml. 4 [Carnell], Seite

80 JDO ODMG Persistence Broker API Persistence Broker Relational DatabaseAPI JDBC Calls Oracle MySQL DB2 Abbildung 18: Architektur von OJB Über OJB.properties lässt sich festlegen, ob OJB in einer einzelnen virtuellen Maschiene oder im Client-Server Modus läuft. Ausserdem lassen sich die Grösse des Connection Pools, sowie Einstellungen zum Locking Management und dem Logging Level der OJB Laufzeitumgebung festlegen Konfiguration der Datenquelle In der Datei repository.xml werden alle Datenbank-relevanten Einstellungen definiert. Als erstes müssen die nötigen Angaben über die JDBC-Verbindung gemacht werden: <?xml version="1.0" encoding="utf-8"?> <!-- defining entities for include-files --> <!DOCTYPE descriptor-repository SYSTEM "repository.dtd" [ <!ENTITY user SYSTEM "repository_user.xml"> <!ENTITY internal SYSTEM "repository_internal.xml"> ]> <descriptor-repository version="0.9.6" isolation-level="read-uncommitted"> <jdbc-connection-descriptor (1) platform="mysql" (2) jdbc-level="2.0" driver="org.gjt.mm.mysql.driver" protocol="jdbc" 80

81 subprotocol="mysql" dbalias="//localhost:3306/ctc_support" username="ctcadmin" password="pal" /> <!-- include user defined mappings here --> &user; (3) <!-- include ojb internal mappings here --> &internal; (4) </descriptor-repository> Die Konfiguration der Datenbank ist relativ einfach. Sie besteht daraus, in einem <jdbcconnection-descriptor> Element alle Datenbank-relevanten an OJB mitzuteilen (1). Die meisten der Attribute werden dazu benötigt, eine JDBC Verbindung zur Datenbank aufzubauen. Um OJB mitzuteilen welche Datenbank verwendet wird, nutzt man das platform Attribut (2). Die restlichen Attribute sind selbsterklärend. Der Übersichtlichkeit halber, werden die Abbildungen selbst in einer separaten Datei definiert und mittels einer Include-Anweisung in die Datei repository.xml eingebunden (3). Auf die selbe Weise werden auch die von OJB benötigten internen Abbildungen importiert (4) Konfiguration der objekt-relationalen Abbildung Da es den Rahmen dieses Dokumentes sprengen würde, die gesamte Abbildungskonfiguration durchzugehen, konzentrieren wir uns an dieser Stelle auf die Abbildung einer einzelnen Klasse. Um nicht mit der Tradition zu brechen, wollen wir als Beispiel wieder den Use-Case Neues Dokument erstellen heranziehen. In den vergangenen Kapiteln haben wir gesehen, welche Schritte in den einzelnen Applikationsschichten notwendig waren, um ein neues Dokument zu erstellen und abzuspeichern. In diesem Abschnitt wollen wir uns nun ansehen, wie die magische Abbildung eines DocumentVO Objekts auf die Datenbanktabellen der Support Portal Datenbank funktioniert. Jede Klasse die von OJB persistent gemacht werden soll, muss über ein <class-descriptor> Element beschrieben werden: <class-descriptor class="ch.ctc.support.document.documentvo" (1) table="t_document"> (2) </class-descriptor> 81

82 Das Attribut class spezifiziert den vollqualifizierten Name der Klasse, die abgebildet werden soll (1). Das table Attribut definiert, auf welche Tabelle in der Datenbank diese Klasse abgebildet werden soll (2). Ein <class-descriptor> Element enthält ein oder mehrere <field-descriptor> Elemente. Diese Elemente werden dazu verwendet, die einzelnen Attribute einer Klasse auf die entsprechenden Felder in der Datenbanktabelle abzubilden. Schauen wir uns als erstes das <field-descriptor> Element für das Attribut _id an: <field-descriptor id="14" (1) name="_id" (2) column="id" (3) jdbc-type="bigint" (4) primarykey="true" (5) autoincrement="true" (6) /> Das Attribut id enthält eine eindeutige Nummer, die den <field-descriptor> identifiziert (1). Die Reihenfolge dieser Nummern muss die Reihenfolge der Felder in der Datenbanktabelle wiederspiegeln. name definiert den Namen das Java Attributs, das abgebildet werden soll (2). column definiert den Namen des Feldes in der Datenbank auf welches das Java Attribut abgebildet wird (3). Das Attribut jdbc-type definiert den OJB Datentypen der für das Abbilden des <field-descriptor> Elements verwendet werden soll (4). In der OJB Dokumentation [OJB] befindet sich eine Tabelle, welche die verfügbaren Datentypen auflistet und beschreibt, auf welche JDBC Datentypen diese abgebildet werden. Das primarykey Attribut spezifiziert, dass dieses Feld als Primärschlüssel abgebildet wird (5). Das letzte Attribut ist autoincrement (6). Dieses teilt OJB mit, dass für jeden neuen Datensatz, der erstellt wird, automatisch ein Sequenzwert erstellt wird, der als Primärschlüssel verwendet wird. Wird autoincrement auf false gesetzt, ist es die Aufgabe des Entwickler einen solchen eindeutigen Wert zu erstellen. Wir wollen uns noch die Abbildung eines zweiten Attributs ansehen. 82

83 <field-descriptor id="15" name="_name" column="name" jdbc-type="varchar" /> Hier fehlen die Attribute primarykey und autoincrement, wie es zu erwarten war. Es handelt sich bei diesem Feld ja nicht um einen Primärschlüssel und deshalb sind diese Attribute nicht notwendig. Der Wert des Attributs id wurde um eins erhöht. Ansonsten bleibt alles beim Alten. Die meisten der restlichen Attribute werden auf die selbe Weise abgebildet und werden daher nicht eingehender beschrieben Abbildung von aggregierten Objekten Die eben gezeigte Abbildung ist im Prinzip nichts anderes als ein simples kopieren eines Attributwertes in ein Feld der Datenbank. Das ist noch keine grosse Errungenschaft. Aber unsere Objekte bestehen ja nicht nur aus primitiven Datentypen. So gehört ein DocumentVO zum Beispiel zu einer Kategorie. Auf der Objektebene unserer Applikation wird diese Beziehung dadurch ausgedrückt, dass ein DocumentVO ein CategoryVO als Attribut enthält. Noch deutlicher wird dieser Sacherverhalt durch die Beziehung zwischen einem Dokument und einem Stichwort. Jedes Dokument kann mehrere Stichworte zugeordnet bekommen. Auf der Objektebene bedeutet das, dass ein DocumentVO eine Collection von KeywordVO Objekten als Attribut hat. Bei solchen Beziehungen kommen die wahren Vorzüge eines objekt-relationalen Mapping Tools zu Vorschein. Müsste man ein solches Verhältnis mit JDBC lösen, wäre das ein ziemlicher Aufwand. Mit OJB ist das Ganze ein Kinderspiel! Das folgende Code-Beispiel zeigt, wie das geschilderte Verhältnis zwischen DocumentVO und CateogoryVO abgebildet wird. <reference-descriptor name="_category" (1) class-ref="ch.ctc.support.category.categoryvo" (2) auto-retrieve="true" (3) auto-update="true" (4) > <foreignkey field-ref="_categoryid"/> (5) </reference-descriptor> 83

84 Das <reference-descriptor> Tag bildet einen ganzen Datensatz aus der Tabelle t_category auf ein CategoryVO Objekt mit Namen _category ab (1). Bei diesem Namen handelt es sich natürlich um das gleichnamige Attribut der Klasse DocumentVO. Das Attribut class-ref (2) teilt OJB mit, welcher Datentyp verwendet werden soll, um die aus der Datenbank gelesenen Daten zu speichern. Die zwei letzten Attribute, auto-retrieve und auto-update, teilen OJB mit, wie es mit dieser Kindbeziehung umgehen soll, wenn eine Operation auf dem Elternobjekt durchgeführt wird. Wenn auto-retrieve auf true gesetzt wird (4), bedeutet dies, dass OJB die Daten für das CategoryVO Objekt automatisch laden soll. Wenn es auf false gesetzt ist, muss sich der Entwickler selber um das Laden dieser Daten kümmern. Das auto-update Attribut (4) kontrolliert, ob Änderungen am Kindobjekt (in unserem Beispiel CategoryVO) automatisch durchgeführt werden, wenn das Elternobjekt persistent gemacht wird. Zum Schluss bleibt nocht das <foreignkey> Element. Dieses Element wird dazu verwendet, OJB mitzuteilen, welches Java Attribut der Elternklasse dazu verwendet werden soll, die Join Operation durchzuführen. In unserem Beispiel wird das Attribut _categoryid verwendet (5), um die mit dem Dokument assoziierte Kategorie ausfindig zu machen. Das Attribut fieldref bezieht sich auf das name Attribut eines <field-descriptor> Elements im selben <class-descriptor> Element. In anderen Worten, im <class-descriptor> für die Klasse DocumentVO muss es ein <field-descriptor> Element geben, das den Namen _categoryid hat. Dieses Feld wird nun zum Auffinden der mit dem DocumentVO assoziierten CategoryVO verwendet. <field-descriptor id="20" name="_categoryid" column="category_id" jdbc-type="bigint" /> Nun haben wir aber noch den komplexesten Fall übrig: die Beziehung zwischen einem Dokument und einem Stichwort. In der Datenbank entspricht dies einer m:n Beziehung die über eine Tabelle names t_keyword_supportitem zerlegt wurde. 84

85 Eine solche Beziehung wird in OJB durch die Verwendung eines <collection-descriptor> Elementes beschrieben. <collection-descriptor name="_collectionofkeywords" (1) element-class-ref="ch.ctc.support.keyword.keywordvo" (2) auto-retrieve="true" auto-update="true" indirection-table="t_keyword_supportitem" (3) > <fk-pointing-to-this-class column="supportitem_id"/> (4) <fk-pointing-to-element-class column="keyword_id"/> (5) </collection-descriptor> Wie schon beim <reference-descriptor> Element, muss über das name Attribut (1) der Name des Java Attributs definiert werden, das die Sammlung von Objekten speichert. Ausserdem muss OJB wissen, von welchem Typ die Objekte in dieser Sammlung sind. Dies wird durch das element-class-ref Attribut beschrieben (2). auto-retrieve und autoupdate habe dieselbe Funktion wie beim <reference-descriptor> Element. Das Attribut indirection-table (3) spezifiziert die Datenbanktabelle, über welche die m:n Beziehung zerlegt wird. In unserem Fall ist dies die Tabelle t_keyword_supportitem. Abbildung 19: m:n Beziehung zwischen Dokument und Stichwort Anstelle des <foreign-key> Elements, haben wir nun zwei neue Elemente. Wir müssen OJB mitteilen, welches Feld der Zerlegungstabelle auf das Dokument verweist, und welches auf das Stichwort. Hierzu verwendet man die Attribute <fk-pointing-to-this-class> und <fk-pointing-to-element-class>. <fk-pointing-to-this-class> definiert, welches 85

86 Feld des indirection-table sich auf die Klasse bezieht die abgebildet wird (4). In unserem Fall bezieht sich das Feld supportitem_id auf das Dokument. <fk-pointing-to-elementclass> definiert hingegen das Feld, das zur anderen Tabelle der m:n Beziehung verweist (5). In unserem Beispiel bezieht sich keyword_id auf ein Stichwort. Wie die gezeigten Beispiele illustrieren, lassen sich mit OJB Klassen so abbilden, wie sie auf Objektebene auch wirklich existieren. Aggregation und Komposition von Objekten wird umfänglich unterstützt. Somit erlaubt einem OJB die Verwendung von Objekten wie sie normalerweise in einer objekt-orientierten Sprache wie Java eingesetzt werden und zwingt den Entwickler nicht zu Kompromissen. Im nächsten Abschnitt wollen wir uns noch kurz mit ein paar weiteren objekt-orientierten Techniken und wie sie von OJB unterstüzt werden befassen Vererbung und Polymorphismus Die Verwendung von Vererbungshierarchien ist in einer objekt-orientierten Sprache Norm. Es ist daher ziemlich einleuchtend, dass ein professionelles objekt-relationales Mapping Tool wie OJB solche Techniken unterstützt. Wie schon in Kapitel 11.5 erwähnt wurde, implementieren die Klassen DocumentVO und DownloadVO die Schnittstelle SupportItemI. Diesem Sachverhalt muss auch bei der objektrelationalen Abbildung Rechnung getragen werden. Im Klartext heisst das, wenn wir eine Sammlung aller Dokument und Software Downloads benötigen, welche mit einem bestimmten Stichwort assoziiert sind, muss uns OJB eine Sammlung aller SupportItemI Objekte zurückliefern, die dieses Stichwort enthalten. Wir müssen OJB also über die Existenz der Schnittstelle SupportItemI aufklären, und auflisten, welche Klassen diese Schnittstelle implementieren. Eine Sammlung von Objekten, die eine Schnittstelle implementieren (oder eine abstrakte Klasse erweitern), wird in der OJB Terminologie Extent genannt. Die Beschreibung des von uns benötigten Extents sieht folgendermassen aus: <class-descriptor class="ch.ctc.support.common.supportitemi"> (1) <extent-class class-ref="ch.ctc.support.download.downloadvo"/> (2) <extent-class class-ref="ch.ctc.support.document.documentvo"/> (3) </class-descriptor> 86

87 Diese Deklaration ist im Prinzip ziemlich selbsterklärend. Man verwendet wie bei einer normalen Klasse ein <class-descriptor> Element. Anstelle eines Klassennamens gibt man für das Attribut class den Namen der Schnittstelle an (1). Nun wird für jede Klasse, die diese Schnittstelle implementiert, ein <extent-class> Element erstellt, dessen einziges Attribut class-ref den vollqualifizierten Namen der Klasse spezifiziert. Um an alle Dokumente und Software Downloads zu gelangen, die ein bestimmtes Stichwort aufweisen, muss ein KeywordVO Objekt eine Sammlung von allen SupportItemI Objekten haben, die mit dem Stichwort assoziiert sind. public class KeywordVO extends ValueObject { } private Collection _collectionofsupportitemis; Die Beschreibung für die Abbildung der Klasse KeywordVO muss also wie folgt aussehen: <class-descriptor class="ch.ctc.support.keyword.keywordvo" table="t_keyword" > <collection-descriptor name="_collectionofsupportitemis" element-class-ref="ch.ctc.support.common.supportitemi" (1) indirection-table="t_keyword_supportitem" > <fk-pointing-to-this-class column="keyword_id"/> <fk-pointing-to-element-class column="supportitem_id"/> </collection-descriptor> </class-descriptor> Der einzige Unterschied zur Abbildung aus der Sicht eines Dokuments ist, dass hier für element-class-ref nicht der Name einer Klasse, sondern der Name einer Schnittstelle angegeben wird (1). Ansonsten funktioniert die Abbildung genau gleich wie beim <collection-descriptor> für KeywordVO Objekte, der im <class-descriptor> der Klasse DocumentVO bereits beschrieben wurde. 87

88 Wie das letzte Beispiel gezeigt hat, lassen sicht mit OJB praktisch alle auf Objektebene vorstellbaren Szenarien abbilden. Ich habe hier aber nur einen Bruchteil der Funktionalität von OJB beschrieben. Es stehen noch jede Menge toller Features zur Verfügung, die auch die Verwendung von OJB in sehr grossen Projekten mit hunderten oder gar tausenden von Tabellen und sehr tiefen Objekt-Hierarchien ermöglichen. Unter [OJB] findet der geneigte Leser reichhaltige Informationen zu diesem Produkt. 88

89 13 Sicherheitsfunktionen Wie in Kapitel 2 bereits beschrieben, stellt die unflexible Zugangskontrolle zum Supportbereich eine der grössten Unzulänglichkeiten der bestehenden Lösung dar. Der geschützte Bereich ist durch einen Benutzernamen und ein Passwort geschützt. Diese Sicherheitsangaben sind jedoch für alle Benutzer dieselben. Zur Zeit besteht also nur die Möglichkeit, einem Benutzer vollen Zugriff zu gewähren, oder jeglichen Zugriff zu unterbinden. Ein weiterer frappanter Nachteil besteht darin, dass durch die Verwendung eines einzigen Benutzernamens und Passwortes die Sicherheit enorm eingeschränkt ist. Die Firma CTC Analytics ist sich bewusst, dass über die Jahre viele Benutzer in Besitz dieser Informationen gelangt sind, die aber nicht für sie bestimmt waren. Ein wichtige Teil dieser Arbeit war also auch eine Verbesserung des Sicherheitskonzeptes. Die Implementation dieses Sicherheitskonzeptes konnte aus zeitlichen Gründen noch nicht fertiggestellt werden. Die Basisfunktionalität ist aber implementiert. In diesem Kapitel werde ich daher vorwiegend auf die Konzeption der Sicherheitsfeatures eingehen und weniger auf deren Implementation Benutzer und Rollen Um eine feinere Abstimmung der Zugangskontrolle zu ermöglichen, wurde beim CTC Support Portal eine komplette Benutzerverwaltung konzipiert und teilweise schon implementiert Da es eine Anforderung der Firma war, Kontrolle darüber zu haben, wem Zugang zum Supportbereich gewährt wird, muss jeder Benutzer von einem Mitarbeiter der Firma CTC authorisiert werden. Dazu muss sich ein Benutzer zuerst über ein HTML Formular registrieren. Seine Daten werden in der Datenbank gespeichert, er hat jedoch solange keinen Zugriff, bis er von einem Mitarbeiter der Firma CTC authorisiert wurde. Dieser Workflow wurde so implementiert, dass jedes Benutzerobjekt ein Attribute authenticated bestitzt. Registriert sich ein Benutzer wird dieses Attribut standardmässig auf false gesetzt. Die Mitarbeiter der Firma CTC haben nun die Möglichkeit, sich über die Administrationskonsole des Support Portals eine Liste mit allen noch nicht authorisierten 89

90 Benutzern anzeigen zu lassen. Der Mitarbeiter kann nun von Fall zu Fall entscheiden, ob einem Benutzer Zugang zum geschützten Bereich gewährt wird oder nicht. Authorisiert der Mitarbeiter einen Benutzer wird das authenticated Attribut auf true gesetzt und der Benutzer hat ab sofort Zugang zum geschützten Bereich. Wird einem Benutzer hingegen der Zugriff auf den geschützten Bereich verweigert, wir das Attribut rejected auf true gesetzt. Die abgelehnten Benutzer werden nicht aus der Datenbank gelöscht. Dies hat zwei Gründe. Erstens kann es sein, dass einem Benutzer zu einem späteren Zeitpunkt der Zugriff gewährt wird (vielleicht nach einem persönlichen Gesprächt mit einem Mitarbeiter). Es wäre umständlich, wenn sich der Benutzer nochmals neu registrieren müsste. Der zweite und vielleicht wichtigere Punkt ist, dass bei der Registrierung eines Benutzers überprüft wird, ob bereits ein Benutzer mit denselben Informationen in der Datenbank vorhanden ist. Ist dies der Fall, wird eine Meldung angezeigt, dass bereits einen Benutzer mit diesen Angaben existiert. Würde ein abgelehnter Benutzer aus der Datenbank gelöscht, könnte sich dieser wieder und wieder registrieren und somit den Mitarbeitern der Firma CTC eine Menge unnötiger Arbeit aufladen. Da es im Moment nur zwei Rollen gibt, reicht eine Authorisierung eines Benutzers aus. In der Struts Action AdmitUserAction wird einem Benutzer automatisch die Rolle eines Service Technicians zugewiesen. Damit hat er Zugang zu allen Dokumenten und Software Downloads. Es ist aber durchaus denkbar, dass die Firma CTC die Zugangskontrolle durch eine feinere Abstufung realisiert wird. Mit der jetzigen Basis, liesse sich diese Funktionalität durch eine einzige zusätzlichde Struts Action (etwa AssignRoleAction) realiseren Rollen-basierter Zugriff auf Dokumente und Downloads Durch die unflexible Zuganskontrolle der bestehenden Lösung, hat die Firma CTC keine Möglichkeit, ein bestimmtes Dokument einer grösseren Benutzergruppe als nur Support Technikern zugänglich zu machen. Wenn einem Benutzer Zugang zum Supportbereich gewährt wird, hat er automatisch Zugriff auf alle Dokumente und Software Downloads. Um diese Einschränkungen zu beheben, wird beim CTC Support Portal jedem Dokument eine Rolle zugeteilt. Dieses Attribut indiziert die Authorisierungsstufe, die ein Benutzer benötigt, um auf das entsprechende Dokument Zugriff zu haben. 90

91 Wenn ein Benutzer also im Knowledge Base Bereich des Support Portals eine Liste von Dokumenten anfordert, wird zuerst seine Rolle überprüft. Diese Rolle wird aus dem UserVO Objekt ausgelesen, das jeder Benutzer in seiner Session Variable hat (mehr dazu später). Wenn nun beispielsweise über die Struts Action BrowseByCategoryAction eine Liste aller Dokumente aus der Datenbank ausgelesen wird, werden die gefundenen Objekte zuerst gefiltert bevor sie dem Benutzer angezeigt werden. Er bekommt nur die Dokumente angezeigt, die seiner Authorisierungsstufe entsprechen. Doch wie kann sichergestellt werden, dass jeder Benutzer ein UserVO Objekt in seiner Session hat, wenn er eine Anfrage abschickt? Dieses Problem kann auf relativ einfache und doch elegante Weise mit Servlet Filtern gelöst werden Servlet Filter Servlet Filter sind ein neue Errungenschaft der Servlet 2.3 API Spezifikation. Filter sind Objekte die eine Anfrage (request) oder eine Antwort (response) modifizieren können. Es sind allerdings keine Servlets. Filter erstellen keine Response Objekte. Sie sind Präprozessoren einer Anfrage bevor diese ein Servlet erreicht und Nachprozessoren einer Antwort die ein Servlet verlässt. Ein Filter kann so konfiguriert werden, dass er auf ein einzelnes oder auf eine Gruppe von Servlets angewendet wird. Jedes Servlet und jede Gruppe von Servlets kann ausserdem von null bis mehreren Filtern gefiltert werden. Die folgende Abbildung illustriert diesen Sachverhalt. 91

92 C L I E N T Request Request Response Response Servlet 1 Servlet 2 Servlet 3 Servlet 4 Servlet Filter Servlet Container Abbildung 20: Funktiosweise von Servlet Filtern Konifguration von Servlet Filtern Um dem Servlet Container mitzuteilen, welche Filter vorhanden sind und mit welchen Servlets diese assoziiert sind, müssen in der Konfigurationsdatei web.xml zwei Elemente definiert werden. Das erste ist das <filter> Element: <filter> <filter-name>userfilter</filter-name> (1) <filter-class>ch.ctc.support.common.userfilter</filter-class> (2) </filter> <filter> <filter-name>adminfilter</filter-name> <filter-class>ch.ctc.support.common.adminfilter</filter-class> </filter> Das <filter> Element einhält zwei weiter Elemente. <filter-name> definiert einen eindeutigen Namen für einen Servlet Filter (1). <filter-class> spezifiziert den vollqualifizierten Namen der Filterklasse (2). Für das CTC Support Portal werden zwei Filter definiert: UserFilter und AdminFilter. Das zweite Element, das benötigt wird, ist <filter-mapping>: 92

93 <filter-mapping> <filter-name>userfilter</filter-name> (1) <url-pattern>/*</url-pattern> (2) </filter-mapping> <filter-mapping> <filter-name>adminfilter</filter-name> <url-pattern>/execute/admin/*</url-pattern> (3) </filter-mapping> Ein <filter-mapping> enthält ebenfalls zwei weitere Elemente. <filter-name> bezieht sich auf den Namen des Filters der abgebildet werden soll (1). Dieser Name muss mit dem <filter-name> Attribut eines <filter> Elements korrespondieren. Das Element <urlmapping> definiert, auf welche URL Muster der Filter angewendet werden soll (2). Der UserFilter wird auf alle eingehenden Anfragen angwendet. Das URL Muster lautet also /*. Der AdminFilter hingegen wird auf alle Anfragen angewendet, welche eine URL anfordern die mit dem String /execute/admin/ beginnt. Nun sind diese beiden Filter aktiv und alle Anfragen an das ActionServlet müssen zuerst diese beiden Filter passieren UserFilter Um sicherstellen zu können, dass jeder Benutzer ein UserVO Objekt in seiner Session gespeichert hat, werden alle eingehenden Anfragen durch den UserFilter geschickt. In diesem Filter wird überprüft ob sich in der Session des Benutzers unter dem Schlüssel user ein UserVO Objekt befindet. Das folgende Code Listing zeigt die Implementation der Klasse UserFilter. public class UserFilter implements Filter { public void dofilter( (1) ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest servletrequest = (HttpServletRequest) request; HttpSession session = servletrequest.getsession(); UserVO user = (UserVO) session.getattribute("user"); (2) // if no session can be found, give the user one if (user == null) { (3) 93

94 } } try { UserDAO userdao = UserDAO.getInstance(); user = (UserVO) userdao.findbypk(constantsi.anonymous_key); (4) } catch (DataAccessException e) { RequestDispatcher rd = servletrequest.getrequestdispatcher("/pages/systemerror.jsp"); rd.forward(request, response); } session.setattribute("user", user); (5) } chain.dofilter(request, response); (6) Bei einem Servlet Filter befindet sich die gesamte Filterlogik in der Methode dofilter(). Zuerst wird überprüft, ob der Benutzer ein UserVO Objekt in seiner Session gespeichert hat (2). Wenn dies nicht der Fall ist (3), wird ihm das UserVO Objekt des Anonymous Benutzers zugewiesen (4) und in der Session gespeichert (5). Bevor wir fertig sind, muss auf dem Objekt FilterChain noch die Methode dofilter aufgerufen werden (6). Dies ist notwendig, da wir ja noch einen weiteren Filter definiert haben, der auch noch durchlaufen werden muss. Über diesen Methodenaufruf wird die dofilter() Methode des nächsten Filters aufgerufen AdminFilter Alle administrativen Aufgaben des CTC Support Portals werden über eine Anfrage an eine URL mit dem Muster /execute/admin/ angestossen. Aufgrund dieser Tatsache lässt sich der Zugang zu den administrativen Funktionen relativ einfach kontrollieren. Alle Anfragen auf URLs, die mit dem Muster /execute/admin/ beginnen, werden durch einen AdminFilter geschickt. Dieser Filter überprüft, ob es sich beim Benutzer, der die Anfrage macht, wirklich um jemanden mit Administratorenrechten handelt. Falls der Benutzer gar kein oder das Anonymous UserVO in seiner Session hat, wird er zum Login Formular geschickt um sich zu authentifizieren. Wenn er jetzt erneut auf eine Administratoren-Seite zugreift und er wirklich ein Administrator ist (d.h. sein UserVO Objekt enthält die Rolle Administrator), wird ihm der Zugriff gewährt. Wenn er hingegen keine Administratorenrechte hat, wird ihm eine Access denied Meldung angezeigt. Das folgende Code Listing zeigt die Implementation der Klasse AdminFilter 94

95 public class AdminFilter implements Filter { public void dofilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest servletrequest = (HttpServletRequest) request; HttpSession session = servletrequest.getsession(); UserVO user = (UserVO) session.getattribute("user"); (1) if ((user == null) (user.getid() == new Long(ConstantsI.ANONYMOUS_KEY))) { (2) // user is not logged in. send her to login page. RequestDispatcher rd = servletrequest.getrequestdispatcher("/execute/setuplogin"); rd.forward(request, response); (3) } // we have a user object. check what roles the user is in. // in case there were changes to the database since the user logged in, // refresh the user data from the database UserManagerBD manager = new UserManagerBD(); try { String userid = user.getid().tostring(); user.setauthenticated(true); user = manager.getuserbypk(userid); (4) } catch (ApplicationException e) { RequestDispatcher rd = servletrequest.getrequestdispatcher("/pages/systemerror.jsp"); rd.forward(request, response); } // User is not an authenticated user and hence no admin if (user == null) { RequestDispatcher rd = servletrequest.getrequestdispatcher("/pages/accessdenied.jsp"); rd.forward(request, response); (5) } Collection roles = user.getroles(); (6) boolean isadmin = false; if (roles!= null) { Iterator i = roles.iterator(); while (i.hasnext()) { RoleVO role = (RoleVO) i.next(); String adminkey = ConstantsI.ADMIN_KEY; String rolename = role.getname(); if (rolename.equals(adminkey)) { isadmin = true; } } if (!isadmin) { (7) // The user is not an admin. send him to the access denied page. RequestDispatcher rd = servletrequest.getrequestdispatcher("/pages/accessdenied.jsp"); 95

96 } rd.forward(request, response); } } } else { (8) // the user is in no role. send him to access denied page. RequestDispatcher rd = servletrequest.getrequestdispatcher("/pages/accessdenied.jsp"); rd.forward(request, response); } chain.dofilter(request, response); Zuerst holen wir das UserVO Objekt des Benutzers aus der Session (1) und überprüfen, ob es null ist oder der Benutzer anonym ist (2). Ist dies der Fall wird er zum Login Formular geschickt (3). Ist ein nichtanonymes UserVO Objekt vorhanden, werden als erstes die Daten des Benutzers aus der Datenbank aufgefrischt (4). Dieser Schritt wird gemacht, weil sich die Daten des Benutzers seit seinem Login geändert haben können (z.b. wenn ein Mitarbeiter der Firma CTC einen neuen Benutzer authorisiert). Wenn der Benutzer nicht unter den authorisierten Benutzern gefunden wird, ist er auch kein Administrator und wird demzufolge zur Access denied Seite geschickt (5). Wenn der Benutzer erfolgreich in der Datenbank verifiziert wurde, werden als nächstes seine Rollen überprüft (6). Falls sich der Benutzer in der Rolle Administrator befindet, wird nichts mehr weiter getan und der Zugriff auf die angeforderte URL wird gewährt. Wenn sich der Benutzer jedoch nicht in der Rolle eines Administrators befindet (7) oder gar keine Rolle zugewiesen hat(8), wird er auf die Access denied Seite weitergeleitet. Mit Hilfe dieses Filters, lässt sich auf relativ einfache Weise feststellen, ob ein Benutzer die nötigen Rechte hat, um auf den Administrationsbereich des Support Portals zuzugreifen. Da jede eingehende Anfrage überprüft wird, ist es für einen potentiellen Angreifer auch relativ schwierig, diesen Sicherheitsmechanismus auszuhebeln. 96

97 14 Verbesserungen und Erweiterungsmöglichkeiten Als ich mit der Diplomarbeit anfing, hatte ich mir das persönliche Ziel gesteckt, eine Applikation zu entwickeln, die am Schluss produktiv einsetzbar ist. Dieses Ziel war rückblickend wohl ein bisschen zu hoch gesteckt. Da ich relativ viel Zeit für die Designphase verwendet habe, wurde die Zeit für die Implementierung sehr knapp. Ich habe mich daher bei der Implementierung hauptsächlich darauf konzentriert, eine solide Basis zu entwickeln auf der in einer weiteren Phase aufgebaut werden kann. Obwohl es sich bei der vorliegenden Arbeit um einen Prototypen handelt, können vor allem die Geschäftslogikund die Datenzugriffsschicht grösstenteils im aktuellen Zustand verwendet werden. In der Präsentationsschicht sind gewisse Use-Cases, die als Kernanforderungen definiert wurden, noch nicht implementiert. Der Hauptgrund dafür ist, dass für jede Struts Action und die damit verbundenen JSP Ansichten immer zuerst die Geschäfts- und Datenzugriffslogik entwickelt werden musste. Diese Tatsache spiegelt sich darin wieder, dass diese beiden Applikationsschichten auch am weitesten fortgeschritten sind. Nachdem ich mit Herrn Altenbach von der Firma CTC über die Verwendung eines professionellen Präsentationsframework diskutiert hatte und die Verwendung eines solchen Frameworks provisorisch beschlossen wurde, machte es auch wenig Sinn, viel Zeit für die Entwicklung von JSP Seiten zu verwenden, die in naher Zukunft durch neue ersetzt werden würden. In diesem Kapitel werden noch ein paar Verbesserungs- und Erweiterungsmöglichkeiten beschrieben, die sich während der Entwicklungsphase und durch die darin gemachten Erfahrungen herauskristallisierten Einsatz eines professionelle Präsentationsframeworks Die von mir erstellen JSP Views sehen nicht besonders professionell aus. Dies hat zwei einfache Gründe. Erstens bin ich kein Webdesigner. Die Gestaltung von professionellen Webseiten wird in der Praxis von professionellen Designern und nicht von Entwicklern erstellt. Der Kompetenzbereich eines Designers liegt in der Gestaltung von visuell ansprechenden Webseiten. Derjenige eines Entwicklers liegt darin, robusten Code zu schreiben, der die Funktionalität einer Webapplikation zur Verfügung stellt. Natürlich gibt 97

98 es eine Überlappung dieser beiden Aufgabenbereiche. Sie sind aber dennoch verschieden und werden in der Praxis auch von verschiedenen Leuten mit entsprechendem Know-How bearbeitet. Der zweite Grund ist Zeitmangel. Das Erstellen von schönen Webseiten benötigt viel Zeit. Die zehn Wochen die für die Konzeption, das Design und die Implementierung des Projekts zur Verfügung standen sind einfach zu kurz, um eine professionell gestaltete Website zu entwickeln. Während der Entwicklung des CTC Support Portals bin ich durch Zufall auf das Präsentationsframework Common-Controls gestossen. Dieses Framework bietet durch umfangreiche Tag Libraries die Möglichkeit, sehr professionelle Gestaltungselemente wie Listen, Baumstrukturen oder Tabbed panes zu erstellen. Nach Rücksprache mit der Firma CTC haben wir uns entschieden, für die Produktionslösung des CTC Support Portals dieses Framework einzusetzen. Die folgende Abbildung zeigt ein Listenelement mit Sortierfunktion für jede einzelne Spalte. Abbildung 21: Listenelement von Common-Controls Der Code der nötig ist um diese Liste zu generieren ist erstaunlich kurz: taglib uri="/web-inf/tlds/cc-controls.tld" prefix="ctrl" %> <ctrl:list id="booklist" action="sample105/bookbrowse" name="booklist" title="book.list.title" 98

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen.

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen. Übersicht Struts Forms Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen. Allgemeines Autor: Sascha Wolski http://www.laliluna.de/tutorials.html

Mehr

FTP-Server einrichten mit automatischem Datenupload für SolarView@Fritzbox

FTP-Server einrichten mit automatischem Datenupload für SolarView@Fritzbox FTP-Server einrichten mit automatischem Datenupload für SolarView@Fritzbox Bitte beachten: Der im folgenden beschriebene Provider "www.cwcity.de" dient lediglich als Beispiel. Cwcity.de blendet recht häufig

Mehr

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 Referentin: Dr. Kelly Neudorfer Universität Hohenheim Was wir jetzt besprechen werden ist eine Frage, mit denen viele

Mehr

Es wird das Struts <html:option> Element erläutert und anhand von kleinen Beispielen der Umgang veranschaulicht.

Es wird das Struts <html:option> Element erläutert und anhand von kleinen Beispielen der Umgang veranschaulicht. Struts Code Peaces Element Es wird das Struts Element erläutert und anhand von kleinen Beispielen der Umgang veranschaulicht. Allgemeines Autor: Sascha Wolski Sebastian Hennebrüder

Mehr

PHP Kurs Online Kurs Analysten Programmierer Web PHP

PHP Kurs Online Kurs Analysten Programmierer Web PHP PHP Kurs Online Kurs Analysten Programmierer Web PHP Akademie Domani info@akademiedomani.de Allgemeines Programm des Kurses PHP Modul 1 - Einführung und Installation PHP-Umgebung Erste Lerneinheit Introduzione

Mehr

Autorisierung. Sicherheit und Zugriffskontrolle & Erstellen einer Berechtigungskomponente

Autorisierung. Sicherheit und Zugriffskontrolle & Erstellen einer Berechtigungskomponente Autorisierung Sicherheit und Zugriffskontrolle & Erstellen einer Berechtigungskomponente Dokumentation zum Referat von Matthias Warnicke und Joachim Schröder Modul: Komponenten basierte Softwareentwickelung

Mehr

InfoPoint vom 9. November 2011

InfoPoint vom 9. November 2011 InfoPoint vom 9. November 2011 Was ist Joomla? Theorie Installation Extensions Administration Demo Joomla ist ein modulares content management system (CMS) Es ermöglicht eine Website zu erstellen und online

Mehr

Guide DynDNS und Portforwarding

Guide DynDNS und Portforwarding Guide DynDNS und Portforwarding Allgemein Um Geräte im lokalen Netzwerk von überall aus über das Internet erreichen zu können, kommt man um die Themen Dynamik DNS (kurz DynDNS) und Portweiterleitung(auch

Mehr

Albert HAYR Linux, IT and Open Source Expert and Solution Architect. Open Source professionell einsetzen

Albert HAYR Linux, IT and Open Source Expert and Solution Architect. Open Source professionell einsetzen Open Source professionell einsetzen 1 Mein Background Ich bin überzeugt von Open Source. Ich verwende fast nur Open Source privat und beruflich. Ich arbeite seit mehr als 10 Jahren mit Linux und Open Source.

Mehr

JSP Grundlagen. JEE Vorlesung Teil 5. Ralf Gitzel ralf_gitzel@hotmail.de

JSP Grundlagen. JEE Vorlesung Teil 5. Ralf Gitzel ralf_gitzel@hotmail.de JSP Grundlagen JEE Vorlesung Teil 5 Ralf Gitzel ralf_gitzel@hotmail.de 1 Übersicht Ralf Gitzel ralf_gitzel@hotmail.de 2 Übersicht JSP Konzept Model-View-Controller mit JSPs JSP Expression Language EL Literale

Mehr

Facebook I-Frame Tabs mit Papoo Plugin erstellen und verwalten

Facebook I-Frame Tabs mit Papoo Plugin erstellen und verwalten Facebook I-Frame Tabs mit Papoo Plugin erstellen und verwalten Seit Anfang Juni 2012 hat Facebook die Static FBML Reiter deaktiviert, so wird es relativ schwierig für Firmenseiten eigene Impressumsreiter

Mehr

Umgang mit der Software ebuddy Ändern von IP Adresse, Firmware und erstellen von Backups von ewon Geräten.

Umgang mit der Software ebuddy Ändern von IP Adresse, Firmware und erstellen von Backups von ewon Geräten. ewon - Technical Note Nr. 001 Version 1.3 Umgang mit der Software ebuddy Ändern von IP Adresse, Firmware und erstellen von Backups von ewon Geräten. 19.10.2006/SI Übersicht: 1. Thema 2. Benötigte Komponenten

Mehr

Konfiguration VLAN's. Konfiguration VLAN's IACBOX.COM. Version 2.0.1 Deutsch 01.07.2014

Konfiguration VLAN's. Konfiguration VLAN's IACBOX.COM. Version 2.0.1 Deutsch 01.07.2014 Konfiguration VLAN's Version 2.0.1 Deutsch 01.07.2014 In diesem HOWTO wird die Konfiguration der VLAN's für das Surf-LAN der IAC-BOX beschrieben. Konfiguration VLAN's TITEL Inhaltsverzeichnis Inhaltsverzeichnis...

Mehr

JSP vs. PHP. Ein persönlicher Vergleich. EQUIcon Software GmbH Jena, Jörg Spilling Frankfurter Treffen 2004. Agenda

JSP vs. PHP. Ein persönlicher Vergleich. EQUIcon Software GmbH Jena, Jörg Spilling Frankfurter Treffen 2004. Agenda JSP vs. PHP Ein persönlicher Vergleich Agenda JSP-Ursprung Warum dann noch PHP ansehen? Der erste Eindruck Ein Beispiel in JSP & PHP: mein Flugbuch Der Versuch eines Vergleichs Fazit Bemerkung alles persönliche

Mehr

PHP - Projekt Personalverwaltung. Erstellt von James Schüpbach

PHP - Projekt Personalverwaltung. Erstellt von James Schüpbach - Projekt Personalverwaltung Erstellt von Inhaltsverzeichnis 1Planung...3 1.1Datenbankstruktur...3 1.2Klassenkonzept...4 2Realisierung...5 2.1Verwendete Techniken...5 2.2Vorgehensweise...5 2.3Probleme...6

Mehr

GITS Steckbriefe 1.9 - Tutorial

GITS Steckbriefe 1.9 - Tutorial Allgemeines Die Steckbriefkomponente basiert auf der CONTACTS XTD Komponente von Kurt Banfi, welche erheblich modifiziert bzw. angepasst wurde. Zuerst war nur eine kleine Änderung der Komponente für ein

Mehr

Version 1.0 Datum 05.06.2008. 1. Anmeldung... 2

Version 1.0 Datum 05.06.2008. 1. Anmeldung... 2 Anmeldung Wochenplatzbörse Spiez Version 1.0 Datum 05.06.2008 Ersteller Oester Emanuel Inhaltsverzeichnis 1. Anmeldung... 2 1.1. Anmeldeseite... 2 1.2. Anmeldung / Registrierung... 4 1.3. Bestätigungs-Email...

Mehr

Agile Vorgehensmodelle in der Softwareentwicklung: Scrum

Agile Vorgehensmodelle in der Softwareentwicklung: Scrum C A R L V O N O S S I E T Z K Y Agile Vorgehensmodelle in der Softwareentwicklung: Scrum Johannes Diemke Vortrag im Rahmen der Projektgruppe Oldenburger Robot Soccer Team im Wintersemester 2009/2010 Was

Mehr

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage .htaccess HOWTO zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage Stand: 21.06.2015 Inhaltsverzeichnis 1. Vorwort...3 2. Verwendung...4 2.1 Allgemeines...4 2.1 Das Aussehen der.htaccess

Mehr

Outlook Web App 2010 Kurzanleitung

Outlook Web App 2010 Kurzanleitung Seite 1 von 6 Outlook Web App 2010 Einleitung Der Zugriff über Outlook Web App ist von jedem Computer der weltweit mit dem Internet verbunden ist möglich. Die Benutzeroberfläche ist ähnlich zum Microsoft

Mehr

OP-LOG www.op-log.de

OP-LOG www.op-log.de Verwendung von Microsoft SQL Server, Seite 1/18 OP-LOG www.op-log.de Anleitung: Verwendung von Microsoft SQL Server 2005 Stand Mai 2010 1 Ich-lese-keine-Anleitungen 'Verwendung von Microsoft SQL Server

Mehr

1. Loggen Sie sich mit Ihrem Benutzernamen in den Hosting-Manager (Confixx) auf Ihrer entsprechenden AREA ein. Automatische Wordpress Installation

1. Loggen Sie sich mit Ihrem Benutzernamen in den Hosting-Manager (Confixx) auf Ihrer entsprechenden AREA ein. Automatische Wordpress Installation Page 1 of 8 Automatische Wordpress Installation Vorwort Wordpress ist eines der bekanntesten und am weitesten verbreiteten CMS-Systeme. CMS steht für Content Management System und heisst, dass mit einem

Mehr

crm-now/ps Webforms Webdesigner Handbuch Erste Ausgabe

crm-now/ps Webforms Webdesigner Handbuch Erste Ausgabe crm-now/ps Webforms Webdesigner Handbuch Erste Ausgabe crm-now/ps Webforms: Webdesigner Handbuch Copyright 2006 crm-now Versionsgeschichte Version 01 2006-08-21 Release Version crm-now c/o im-netz Neue

Mehr

Bauteilattribute als Sachdaten anzeigen

Bauteilattribute als Sachdaten anzeigen Mit den speedikon Attributfiltern können Sie die speedikon Attribute eines Bauteils als MicroStation Sachdaten an die Elemente anhängen Inhalte Was ist ein speedikon Attribut?... 3 Eigene Attribute vergeben...

Mehr

! " # $ " % & Nicki Wruck worldwidewruck 08.02.2006

!  # $  % & Nicki Wruck worldwidewruck 08.02.2006 !"# $ " %& Nicki Wruck worldwidewruck 08.02.2006 Wer kennt die Problematik nicht? Die.pst Datei von Outlook wird unübersichtlich groß, das Starten und Beenden dauert immer länger. Hat man dann noch die.pst

Mehr

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 von Markus Mack Stand: Samstag, 17. April 2004 Inhaltsverzeichnis 1. Systemvorraussetzungen...3 2. Installation und Start...3 3. Anpassen der Tabelle...3

Mehr

JSP und Servlet Programmierung

JSP und Servlet Programmierung Seminarunterlage Version: 5.02 Copyright Version 5.02 vom 1. März 2013 Dieses Dokument wird durch die veröffentlicht. Copyright. Alle Rechte vorbehalten. Alle Produkt- und Dienstleistungs-Bezeichnungen

Mehr

Hilfedatei der Oden$-Börse Stand Juni 2014

Hilfedatei der Oden$-Börse Stand Juni 2014 Hilfedatei der Oden$-Börse Stand Juni 2014 Inhalt 1. Einleitung... 2 2. Die Anmeldung... 2 2.1 Die Erstregistrierung... 3 2.2 Die Mitgliedsnummer anfordern... 4 3. Die Funktionen für Nutzer... 5 3.1 Arbeiten

Mehr

Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken.

Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken. Seite erstellen Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken. Es öffnet sich die Eingabe Seite um eine neue Seite zu erstellen. Seiten Titel festlegen Den neuen

Mehr

Zur Bestätigung wird je nach Anmeldung (Benutzer oder Administrator) eine Meldung angezeigt:

Zur Bestätigung wird je nach Anmeldung (Benutzer oder Administrator) eine Meldung angezeigt: K U R Z A N L E I T U N G D A S R Z L WE B - P O R T A L D E R R Z L N E W S L E T T E R ( I N F O - M A I L ) RZL Software GmbH Riedauer Straße 15 4910 Ried im Innkreis Version: 11. Juni 2012 / mw Bitte

Mehr

Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage

Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage Inhaltsverzeichnis 1. Anmeldung... 2 1.1 Startbildschirm... 3 2. Die PDF-Dateien hochladen... 4 2.1 Neue PDF-Datei erstellen... 5 3. Obelix-Datei

Mehr

Live Update (Auto Update)

Live Update (Auto Update) Live Update (Auto Update) Mit der Version 44.20.00 wurde moveit@iss+ um die Funktion des Live Updates (in anderen Programmen auch als Auto Update bekannt) für Programm Updates erweitert. Damit Sie auch

Mehr

http://www.hoststar.ch

http://www.hoststar.ch Kapitel 16 Seite 1 Die eigene Homepage Im Internet finden Sie viele Anbieter, die Ihnen rasch und zuverlässig einen Webhost für die eigene Homepage einrichten. Je nach Speicherplatz und Technologie (E-Mail,

Mehr

:: Anleitung Hosting Server 1cloud.ch ::

:: Anleitung Hosting Server 1cloud.ch :: :: one source ag :: Technopark Luzern :: D4 Platz 4 :: CH-6039 Root-Längenbold LU :: :: Fon +41 41 451 01 11 :: Fax +41 41 451 01 09 :: info@one-source.ch :: www.one-source.ch :: :: Anleitung Hosting Server

Mehr

Komponenten & Hypermedia Seminar Prof. Dr. Frank Thiesing Struts Java-Framework für Web-Applikationen. Referenten: Fabian Bartelt Jens de Witt

Komponenten & Hypermedia Seminar Prof. Dr. Frank Thiesing Struts Java-Framework für Web-Applikationen. Referenten: Fabian Bartelt Jens de Witt Komponenten & Hypermedia Seminar Prof. Dr. Frank Thiesing Struts Java-Framework für Web-Applikationen Referenten: Fabian Bartelt Jens de Witt - Struts 1 Inhaltsverzeichnis Was ist Struts? Vorkenntnisse

Mehr

Adami CRM - Outlook Replikation User Dokumentation

Adami CRM - Outlook Replikation User Dokumentation Adami CRM - Outlook Replikation User Dokumentation Die neue Eigenschaft der Adami CRM Applikation macht den Information Austausch mit Microsoft Outlook auf vier Ebenen möglich: Kontakte, Aufgaben, Termine

Mehr

Leichte-Sprache-Bilder

Leichte-Sprache-Bilder Leichte-Sprache-Bilder Reinhild Kassing Information - So geht es 1. Bilder gucken 2. anmelden für Probe-Bilder 3. Bilder bestellen 4. Rechnung bezahlen 5. Bilder runterladen 6. neue Bilder vorschlagen

Mehr

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert Beamen in EEP Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert Zuerst musst du dir 2 Programme besorgen und zwar: Albert, das

Mehr

Die Formatierungsregeln (die so genannte Wiki-Syntax) für Texte in DokuWiki sind zu großen Teilen die selben, wie in anderen Wiki-Systemen.

Die Formatierungsregeln (die so genannte Wiki-Syntax) für Texte in DokuWiki sind zu großen Teilen die selben, wie in anderen Wiki-Systemen. DokuWiki Kurzanleitung DokuWiki ein sehr einfach zu installierendes und anzuwendendes Wiki und bietet einige Funktionen, welche das Erstellen von Hypertexten, Dokumentationen und Präsentation von Projekten

Mehr

FTP-Leitfaden RZ. Benutzerleitfaden

FTP-Leitfaden RZ. Benutzerleitfaden FTP-Leitfaden RZ Benutzerleitfaden Version 1.4 Stand 08.03.2012 Inhaltsverzeichnis 1 Einleitung... 3 1.1 Zeitaufwand... 3 2 Beschaffung der Software... 3 3 Installation... 3 4 Auswahl des Verbindungstyps...

Mehr

Alle alltäglichen Aufgaben können auch über das Frontend durchgeführt werden, das in den anderen Anleitungen erläutert wird.

Alle alltäglichen Aufgaben können auch über das Frontend durchgeführt werden, das in den anderen Anleitungen erläutert wird. Der Admin-Bereich im Backend Achtung: Diese Anleitung gibt nur einen groben Überblick über die häufigsten Aufgaben im Backend-Bereich. Sollten Sie sich nicht sicher sein, was genau Sie gerade tun, dann

Mehr

Inhalt: Ihre persönliche Sedcard... 1 Login... 1 Passwort vergessen... 2 Profildaten bearbeiten... 3

Inhalt: Ihre persönliche Sedcard... 1 Login... 1 Passwort vergessen... 2 Profildaten bearbeiten... 3 Inhalt: Ihre persönliche Sedcard..... 1 Login... 1 Passwort vergessen... 2 Profildaten bearbeiten... 3 Passwort ändern... 3 email ändern... 4 Sedcard-Daten bearbeiten... 4 Logout... 7 Ich kann die Sedcard

Mehr

Kleines Handbuch zur Fotogalerie der Pixel AG

Kleines Handbuch zur Fotogalerie der Pixel AG 1 1. Anmelden an der Galerie Um mit der Galerie arbeiten zu können muss man sich zuerst anmelden. Aufrufen der Galerie entweder über die Homepage (www.pixel-ag-bottwartal.de) oder über den direkten Link

Mehr

Übungen zur Softwaretechnik

Übungen zur Softwaretechnik Technische Universität München Fakultät für Informatik Lehrstuhl IV: Software & Systems Engineering Markus Pister, Dr. Bernhard Rumpe WS 2002/2003 Lösungsblatt 9 17. Dezember 2002 www4.in.tum.de/~rumpe/se

Mehr

Installation der SAS Foundation Software auf Windows

Installation der SAS Foundation Software auf Windows Installation der SAS Foundation Software auf Windows Der installierende Benutzer unter Windows muss Mitglied der lokalen Gruppe Administratoren / Administrators sein und damit das Recht besitzen, Software

Mehr

EJB Beispiel. JEE Vorlesung 10. Ralf Gitzel ralf_gitzel@hotmail.de

EJB Beispiel. JEE Vorlesung 10. Ralf Gitzel ralf_gitzel@hotmail.de EJB Beispiel JEE Vorlesung 10 Ralf Gitzel ralf_gitzel@hotmail.de 1 Stundenkonzept Gemeinsame Übung Stoff der letzten Stunde wird gemeinsam in einem Beispiel umgesetzt Details werden nochmals erklärt bzw.

Mehr

Internationales Altkatholisches Laienforum

Internationales Altkatholisches Laienforum Internationales Altkatholisches Laienforum Schritt für Schritt Anleitung für die Einrichtung eines Accounts auf admin.laienforum.info Hier erklären wir, wie ein Account im registrierten Bereich eingerichtet

Mehr

Fassade. Objektbasiertes Strukturmuster. C. Restorff & M. Rohlfing

Fassade. Objektbasiertes Strukturmuster. C. Restorff & M. Rohlfing Fassade Objektbasiertes Strukturmuster C. Restorff & M. Rohlfing Übersicht Motivation Anwendbarkeit Struktur Teilnehmer Interaktion Konsequenz Implementierung Beispiel Bekannte Verwendung Verwandte Muster

Mehr

OWASP Stammtisch München Sep 2014 XSS und andere Sicherheitslücken aus der Perspektive des Programmcodes

OWASP Stammtisch München Sep 2014 XSS und andere Sicherheitslücken aus der Perspektive des Programmcodes OWASP Stammtisch München Sep 2014 XSS und andere Sicherheitslücken aus der Perspektive des Programmcodes 1 XSS: Cross-Site Scripting 1.) Es gelangen Daten in den Web-Browser, die Steuerungsinformationen

Mehr

Erste Schritte mit WordPress Anleitung WordPress Version 2.8.X

Erste Schritte mit WordPress Anleitung WordPress Version 2.8.X Erste Schritte mit WordPress Anleitung WordPress Version 2.8.X Login Rufen Sie die Login Seite auf: http://ihren-domainname.ch/wp-login.php Melden Sie sich mit dem Login an: Username Passwort Seiten Aktualisieren

Mehr

SAMMEL DEINE IDENTITÄTEN::: NINA FRANK :: 727026 :: WINTERSEMESTER 08 09

SAMMEL DEINE IDENTITÄTEN::: NINA FRANK :: 727026 :: WINTERSEMESTER 08 09 SAMMEL DEINE IDENTITÄTEN::: :: IDEE :: Ich selbst habe viele verschiedene Benutzernamen und Passwörter und wenn ich mir diese nicht alle aufschreiben würde, würde ich alle durcheinander bringen oder welche

Mehr

4 Aufzählungen und Listen erstellen

4 Aufzählungen und Listen erstellen 4 4 Aufzählungen und Listen erstellen Beim Strukturieren von Dokumenten und Inhalten stellen Listen und Aufzählungen wichtige Werkzeuge dar. Mit ihnen lässt sich so ziemlich alles sortieren, was auf einer

Mehr

Beheben von verlorenen Verknüpfungen 20.06.2005

Beheben von verlorenen Verknüpfungen 20.06.2005 Vor folgender Situation ist sicher jeder Solid Edge-Anwender beim Öffnen von Baugruppen oder Drafts schon einmal gestanden: Die Ursache dafür kann sein: Die Dateien wurden über den Explorer umbenannt:

Mehr

Kurzinformation Zugang zur NOVA für dezentrale Administratoren

Kurzinformation Zugang zur NOVA für dezentrale Administratoren Kurzinformation Zugang zur NOVA für dezentrale Administratoren Unter dieser URL können Sie sich mit Ihrem Benutzernamen und PW anmelden: www.login.eservice-drv.de/elogin Nach erfolgreicher Anmeldung mit

Mehr

Updatebeschreibung JAVA Version 3.6 und Internet Version 1.2

Updatebeschreibung JAVA Version 3.6 und Internet Version 1.2 Updatebeschreibung JAVA Version 3.6 und Internet Version 1.2 Hier finden Sie die Beschreibung der letzten Änderungen und Aktualisierungen. Bei Fragen und Anregungen steht das EDI-Real-Team unter +43 732

Mehr

Kommunikations-Parameter

Kommunikations-Parameter KNX App knxpresso für Android Tablets/Phones Kommunikations-Parameter Ausgabe Dokumentation: Mai. 2015 Doku Version V1.0.0 - Seite 1/8 Inhaltsverzeichnis 1.1 Nützliche Links... 3 1.2 Beschreibung der Kommunikations-Datei...

Mehr

MO 27. Aug. 2007, 17:00 UHR JAVA FRAMEWORKS TIPPS VON PROFI-GÄRTNERN GEGEN WILDWUCHS

MO 27. Aug. 2007, 17:00 UHR JAVA FRAMEWORKS TIPPS VON PROFI-GÄRTNERN GEGEN WILDWUCHS 072 MO 27. Aug. 2007, 17:00 UHR JAVA FRAMEWORKS TIPPS VON PROFI-GÄRTNERN GEGEN WILDWUCHS Die Flut von Open Source Frameworks ist vergleichbar mit dem Markt von kommerziellen Produkten Es gibt eine Vielzahl

Mehr

Online Banking System

Online Banking System Online Banking System Pflichtenheft im Rahmen des WI-Praktikum bei Thomas M. Lange Fachhochschule Giessen-Friedberg Fachbereich MNI Studiengang Informatik Erstellt von: Eugen Riske Yueksel Korkmaz Alper

Mehr

EasyWk DAS Schwimmwettkampfprogramm

EasyWk DAS Schwimmwettkampfprogramm EasyWk DAS Schwimmwettkampfprogramm Arbeiten mit OMEGA ARES 21 EasyWk - DAS Schwimmwettkampfprogramm 1 Einleitung Diese Präsentation dient zur Darstellung der Zusammenarbeit zwischen EasyWk und der Zeitmessanlage

Mehr

4 Arbeiten mit einfachen Actions

4 Arbeiten mit einfachen Actions 29 4.1 Das»C«in Model-View-Controller Der Controller ist der Mechanismus, der den Applikationsfluss verwaltet. In Struts wird diese Managementrolle von einem zentralen ActionServlet übernommen. Die Regeln

Mehr

KURZANLEITUNG CLOUD OBJECT STORAGE

KURZANLEITUNG CLOUD OBJECT STORAGE KURZANLEITUNG CLOUD OBJECT STORAGE Version 1.12 01.07.2014 SEITE _ 2 INHALTSVERZEICHNIS 1. Einleitung... Seite 03 2. Anmelden am Cloud&Heat Dashboard... Seite 04 3. Anlegen eines Containers... Seite 05

Mehr

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem Fachbericht zum Thema: Anforderungen an ein Datenbanksystem von André Franken 1 Inhaltsverzeichnis 1 Inhaltsverzeichnis 1 2 Einführung 2 2.1 Gründe für den Einsatz von DB-Systemen 2 2.2 Definition: Datenbank

Mehr

Erstellung eines Frameworks für Shop Systeme im Internet auf Basis von Java

Erstellung eines Frameworks für Shop Systeme im Internet auf Basis von Java Erstellung eines Frameworks für Shop Systeme im Internet auf Basis von Java Präsentation zur Diplomarbeit von Übersicht Java 2 Enterprise Edition Java Servlets JavaServer Pages Enterprise JavaBeans Framework

Mehr

Sichere E-Mail Kommunikation mit Ihrer Sparkasse

Sichere E-Mail Kommunikation mit Ihrer Sparkasse Ein zentrales Anliegen der Sparkasse Freyung-Grafenau ist die Sicherheit der Bankgeschäfte unserer Kunden. Vor dem Hintergrund zunehmender Wirtschaftskriminalität im Internet und aktueller Anforderungen

Mehr

Task: Nmap Skripte ausführen

Task: Nmap Skripte ausführen Task: Nmap Skripte ausführen Inhalt Einfache Netzwerkscans mit NSE Ausführen des Scans Anpassung der Parameter Einleitung Copyright 2009-2015 Greenbone Networks GmbH Herkunft und aktuellste Version dieses

Mehr

Firewalls für Lexware Info Service konfigurieren

Firewalls für Lexware Info Service konfigurieren Firewalls für Lexware Info Service konfigurieren Inhaltsverzeichnis: 1. MANUELLER DOWNLOAD 1 2. ALLGEMEIN 1 3. EINSTELLUNGEN 1 4. BITDEFENDER VERSION 10 2 5. GDATA INTERNET SECURITY 2007 4 6. ZONE ALARM

Mehr

2.1 Grundlagen: Anmelden am TYPO3-Backend

2.1 Grundlagen: Anmelden am TYPO3-Backend 1 Grundlagen: Anmelden am TYPO3-Backend Zum Anmelden am TYPO3-Backend (dem Content Management System) tippen Sie in der Adresszeile Ihres Browsers (wir empfehlen Mozilla Firefox) hinter uni-bremen.de /typo3

Mehr

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter 2 Inhaltsverzeichnis 1 Web-Kürzel 4 1.1 Einführung.......................................... 4 1.2 Web-Kürzel.........................................

Mehr

KURZANLEITUNG CYBERDUCK MIT CLOUD OBJECT STORAGE

KURZANLEITUNG CYBERDUCK MIT CLOUD OBJECT STORAGE KURZANLEITUNG CYBERDUCK MIT CLOUD OBJECT STORAGE Version 1.12 01.07.2014 SEITE _ 2 INHALTSVERZEICHNIS 1. Einleitung...Seite 03 2. Zugriff auf Cloud Object Storage mit Cyberduck...Seite 04 3. Neuen Container

Mehr

ESB - Elektronischer Service Bericht

ESB - Elektronischer Service Bericht Desk Software & Consulting GmbH ESB - Elektronischer Service Bericht Dokumentation des elektronischen Serviceberichts Matthias Hoffmann 25.04.2012 DESK Software und Consulting GmbH Im Heerfeld 2-4 35713

Mehr

Universal Dashboard auf ewon Alarmübersicht auf ewon eigener HTML Seite.

Universal Dashboard auf ewon Alarmübersicht auf ewon eigener HTML Seite. ewon - Technical Note Nr. 003 Version 1.2 Universal Dashboard auf ewon Alarmübersicht auf ewon eigener HTML Seite. Übersicht 1. Thema 2. Benötigte Komponenten 3. Downloaden der Seiten und aufspielen auf

Mehr

Eine Anwendung mit InstantRails 1.7

Eine Anwendung mit InstantRails 1.7 Eine Anwung mit InstantRails 1.7 Beschrieben wird das Anlegen einer einfachen Rails-Anwung, die ohne Datenbank auskommt. Schwerpunktmäßig wird auf den Zusammenhang von Controllern, Views und der zugehörigen

Mehr

Inhalt. meliarts. 1. Allgemeine Informationen... 2 2. Administration... 2 2.1 Aufruf... 2 2.2 Das Kontextmenü... 3 3. E-Mail Vorlagen...

Inhalt. meliarts. 1. Allgemeine Informationen... 2 2. Administration... 2 2.1 Aufruf... 2 2.2 Das Kontextmenü... 3 3. E-Mail Vorlagen... Inhalt 1. Allgemeine Informationen... 2 2. Administration... 2 2.1 Aufruf... 2 2.2 Das Kontextmenü... 3 3. E-Mail Vorlagen... 4 Seite 1 von 7 meliarts 1. Allgemeine Informationen meliarts ist eine Implementierung

Mehr

Fotostammtisch-Schaumburg

Fotostammtisch-Schaumburg Der Anfang zur Benutzung der Web Seite! Alles ums Anmelden und Registrieren 1. Startseite 2. Registrieren 2.1 Registrieren als Mitglied unser Stammtischseite Wie im Bild markiert jetzt auf das Rote Register

Mehr

Übersicht... 2 Dateiupload... 3 Administratorfunktionen... 4

Übersicht... 2 Dateiupload... 3 Administratorfunktionen... 4 Inhalt Übersicht... 2 Dateiupload... 3 Administratorfunktionen... 4 Benutzer hinzufügen... 4 Benutzerverwaltung... 5 Ordner anlegen... 6 Rechteverwaltung... 7 Verlag für neue Medien Seite 1 Übersicht Mit

Mehr

Erfassen von Service-Meldungen über das Web-Interface auf www.peras.de

Erfassen von Service-Meldungen über das Web-Interface auf www.peras.de Erfassen von Service-Meldungen über das Web-Interface auf www.peras.de Web Self Service Erfassen von Service-Meldungen Version 3.1 Seite 2 von 12 Anwenderdokumentation Version 3.1 Stand September 2011

Mehr

Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote

Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote Zweck dieser Anleitung ist es einen kleinen Überblick über die Funktion Last Minute auf Swisshotelportal zu erhalten. Für das erstellen

Mehr

WordPress. Dokumentation

WordPress. Dokumentation WordPress Dokumentation Backend-Login In das Backend gelangt man, indem man hinter seiner Website-URL einfach ein /wp-admin dranhängt www.domain.tld/wp-admin Dabei gelangt man auf die Administrationsoberfläche,

Mehr

Diese Anleitung wurde erstellt von Niclas Lüchau und Daniel Scherer. Erste Anmeldung. Schritt 1: Anmeldung..2. Schritt 2: Passwort setzen 3

Diese Anleitung wurde erstellt von Niclas Lüchau und Daniel Scherer. Erste Anmeldung. Schritt 1: Anmeldung..2. Schritt 2: Passwort setzen 3 Diese Anleitung wurde erstellt von Niclas Lüchau und Daniel Scherer Inhalt Erste Anmeldung. Schritt 1: Anmeldung..2 Schritt 2: Passwort setzen 3 Schritt 3: Nachträgliches Ändern des Passworts..4 Schreiben

Mehr

Tutorial: Wie kann ich Dokumente verwalten?

Tutorial: Wie kann ich Dokumente verwalten? Tutorial: Wie kann ich Dokumente verwalten? Im vorliegenden Tutorial lernen Sie, wie Sie in myfactory Dokumente verwalten können. Dafür steht Ihnen in myfactory eine Dokumenten-Verwaltung zur Verfügung.

Mehr

Einleitung: Frontend Backend

Einleitung: Frontend Backend Die Internetseite des LSW Deutschland e.v. hat ein neues Gesicht bekommen. Ab dem 01.01.2012 ist sie in Form eines Content Management Systems (CMS) im Netz. Einleitung: Die Grundlage für die Neuprogrammierung

Mehr

Kurzanleitung GigaMove

Kurzanleitung GigaMove Kurzanleitung GigaMove Dezember 2014 Inhalt Kurzerklärung... 1 Erstellen eines neuen Benutzerkontos... 2 Login... 5 Datei bereitstellen... 6 Bereitgestellte Datei herunterladen... 6 Datei anfordern...

Mehr

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster Es gibt in Excel unter anderem die so genannten Suchfunktionen / Matrixfunktionen Damit können Sie Werte innerhalb eines bestimmten Bereichs suchen. Als Beispiel möchte ich die Funktion Sverweis zeigen.

Mehr

Software Download Bestellungen Der Bestellablauf

Software Download Bestellungen Der Bestellablauf Software Download Bestellungen Der Bestellablauf Software Downloadbestellungen können normal via intouch, Telefon, E-Mail oder eine nähere Integrationsmöglichkeit getätigt werden. In dieser Dokumentation

Mehr

etutor Benutzerhandbuch XQuery Benutzerhandbuch Georg Nitsche

etutor Benutzerhandbuch XQuery Benutzerhandbuch Georg Nitsche etutor Benutzerhandbuch Benutzerhandbuch XQuery Georg Nitsche Version 1.0 Stand März 2006 Versionsverlauf: Version Autor Datum Änderungen 1.0 gn 06.03.2006 Fertigstellung der ersten Version Inhaltsverzeichnis:

Mehr

Anbindung an easybill.de

Anbindung an easybill.de Anbindung an easybill.de Stand: 14. Dezember 2011 2011 Virthos Systems GmbH www.pixtacy.de Einleitung Pixtacy verfügt ab Version 2.3 über eine Schnittstelle zu dem Online-Fakturierungsprogramm easybill.de.

Mehr

Punkt 1 bis 11: -Anmeldung bei Schlecker und 1-8 -Herunterladen der Software

Punkt 1 bis 11: -Anmeldung bei Schlecker und 1-8 -Herunterladen der Software Wie erzeugt man ein Fotobuch im Internet bei Schlecker Seite Punkt 1 bis 11: -Anmeldung bei Schlecker und 1-8 -Herunterladen der Software Punkt 12 bis 24: -Wir arbeiten mit der Software 8-16 -Erstellung

Mehr

Tutorial - www.root13.de

Tutorial - www.root13.de Tutorial - www.root13.de Netzwerk unter Linux einrichten (SuSE 7.0 oder höher) Inhaltsverzeichnis: - Netzwerk einrichten - Apache einrichten - einfaches FTP einrichten - GRUB einrichten Seite 1 Netzwerk

Mehr

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen.

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen. Datenbank-Verschlüsselung mit DbDefence und Webanwendungen. In diesem Artikel werden wir Ihnen zeigen, wie Sie eine Datenbank verschlüsseln können, um den Zugriff einzuschränken, aber trotzdem noch eine

Mehr

Swisscom TV Medien Assistent

Swisscom TV Medien Assistent Swisscom TV Medien Assistent Mithilfe dieses Assistenten können Sie Fotos und Musik, die Sie auf Ihrem Computer freigegeben haben, auf Swisscom TV geniessen. Diese Bedienungsanleitung richtet sich an die

Mehr

Daten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen

Daten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen Daten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen Inhalt 1. Die Funambol Software... 3 2. Download und Installation... 3 3.

Mehr

Upgrade auf die Standalone Editionen von Acronis Backup & Recovery 10. Technische Informationen (White Paper)

Upgrade auf die Standalone Editionen von Acronis Backup & Recovery 10. Technische Informationen (White Paper) Upgrade auf die Standalone Editionen von Acronis Backup & Recovery 10 Technische Informationen (White Paper) Inhaltsverzeichnis 1. Über dieses Dokument... 3 2. Überblick... 3 3. Upgrade Verfahren... 4

Mehr

Video-Tutorial: Einrichten einer Facebook Landing Page in der Facebook Chronik (Timeline)

Video-Tutorial: Einrichten einer Facebook Landing Page in der Facebook Chronik (Timeline) Video-Tutorial: Einrichten einer Facebook Landing Page in der Facebook Chronik (Timeline) Skript Nivea hat eine Die Telekom hat eine Microsoft hat eine Und selbst die BILD-Zeitung hat eine Wovon ich spreche?

Mehr

Bedienungsanleitung für den SecureCourier

Bedienungsanleitung für den SecureCourier Bedienungsanleitung für den SecureCourier Wo kann ich den SecureCourier nach der Installation auf meinem Computer finden? Den SecureCourier finden Sie dort, wo Sie mit Dateien umgehen und arbeiten. Bei

Mehr

E-Government Sondertransporte (SOTRA) Registrierung von Benutzerkennung

E-Government Sondertransporte (SOTRA) Registrierung von Benutzerkennung E-Government Sondertransporte (SOTRA) Registrierung von Benutzerkennung Projektteam Sondertransporte Land OÖ Version September 2012 Alle Rechte, insbesondere das Recht der Vervielfältigung, Verbreitung

Mehr

Adobe Photoshop. Lightroom 5 für Einsteiger Bilder verwalten und entwickeln. Sam Jost

Adobe Photoshop. Lightroom 5 für Einsteiger Bilder verwalten und entwickeln. Sam Jost Adobe Photoshop Lightroom 5 für Einsteiger Bilder verwalten und entwickeln Sam Jost Kapitel 2 Der erste Start 2.1 Mitmachen beim Lesen....................... 22 2.2 Für Apple-Anwender.........................

Mehr

Web Services stellen eine Integrationsarchitektur dar, die die Kommunikation zwischen verschiedenen Anwendungen

Web Services stellen eine Integrationsarchitektur dar, die die Kommunikation zwischen verschiedenen Anwendungen 9 3 Web Services 3.1 Überblick Web Services stellen eine Integrationsarchitektur dar, die die Kommunikation zwischen verschiedenen Anwendungen mit Hilfe von XML über das Internet ermöglicht (siehe Abb.

Mehr

Anleitung öffentlicher Zugang einrichten

Anleitung öffentlicher Zugang einrichten TRK-DashBoard Anleitung öffentlicher Zugang einrichten Manual für Kunden VERSION DATUM AUTOR DATEINAME 1.0 8. SEPTEMBER 2011 HRR ANLEITUNG_OEFFENTLICHER_ZUGANG_DASHBOARD_V10 INHALT 1 ALLGEMEINE INFORMATIONEN...

Mehr

Datenaustausch mit dem BVK Data Room

Datenaustausch mit dem BVK Data Room BEDIENUNGSANLEITUNG FÜR ANGESCHLOSSENE ARBEITGEBER Datenaustausch mit dem BVK Data Room In diesem Manual erfahren Sie, wie Sie den «Data Room» (Datenlogistik ZH) der BVK bedienen. Anmeldung und Login im

Mehr