05.02.2013 Aufrufe

Ausarbeitung - Institut für Wirtschaftsinformatik der WWU Münster ...

Ausarbeitung - Institut für Wirtschaftsinformatik der WWU Münster ...

Ausarbeitung - Institut für Wirtschaftsinformatik der WWU Münster ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

Themensteller: Prof. Dr. Herbert Kuchen<br />

Betreuer: Christian Hermanns<br />

<strong>Institut</strong> <strong>für</strong> <strong>Wirtschaftsinformatik</strong><br />

Praktische Informatik in <strong>der</strong> Wirtschaft<br />

Westfälische Wilhelms-Universität <strong>Münster</strong><br />

<strong>Ausarbeitung</strong><br />

Application Frameworks<br />

im Rahmen des Seminars Software Engineering<br />

Birgit Hecker


Inhaltsverzeichnis<br />

1 Aufbau und Ziel <strong>der</strong> Arbeit ........................................................................................ 1<br />

2 Grundlagen ................................................................................................................ 2<br />

2.1 Application Framework ..................................................................................... 2<br />

2.2 Dependency Injection ......................................................................................... 3<br />

2.3 Aspektorientierte Programmierung .................................................................... 4<br />

3 Spring Framework ..................................................................................................... 5<br />

3.1 Beispielanwendung Bibliothek .......................................................................... 5<br />

3.2 Spring-Container ................................................................................................ 6<br />

3.3 Spring-Bean........................................................................................................ 7<br />

3.4 Dependency Injection ......................................................................................... 7<br />

3.5 Aspektorientierte Programmierung .................................................................. 10<br />

3.6 Model View Controller .................................................................................... 11<br />

3.7 Datenbankzugriff .............................................................................................. 14<br />

3.8 Sicherheit .......................................................................................................... 17<br />

4 Vergleich Spring und Java EE ................................................................................. 21<br />

5 Zusammenfassung und Ausblick ............................................................................. 22<br />

Anhang A: Klassendiagramm ......................................................................................... 23<br />

Anhang B: Quellcode ...................................................................................................... 24<br />

Literaturverzeichnis ........................................................................................................ 60<br />

II


Kapitel 1: Aufbau und Ziel <strong>der</strong> Arbeit<br />

1 Aufbau und Ziel <strong>der</strong> Arbeit<br />

Die Nachfrage nach Geschäftsanwendungen im Java-Bereich steigt. Dabei werden die<br />

Anwendungen immer komplexer. Folgen davon sind, dass eine einfache Verwendung<br />

von Java ohne Bibliotheken nicht möglich ist. Eine Bibliothek stellt Funktionen zu<br />

bestimmten Aufgabenstellungen bereit, in Form einer Sammlung von Klassen dieses<br />

Aufgabengebietes. Die Einarbeitung in eine solche Anwendung ist <strong>für</strong> den Entwickler<br />

sehr zeitintensiv. Einen Ausweg bieten Frameworks. Sie stellen eine Schicht über<br />

verschiedene Bibliotheken dar und vereinfachen somit die Softwareentwicklung [Wo07,<br />

Kap. 1.1]. Frameworks enthalten bereits Funktionalität, die in die eigentliche<br />

Implementierung eingebunden werden kann. Im Gegensatz zur Bibliothek aus <strong>der</strong> <strong>der</strong><br />

Programmierer bei Bedarf einzelne Klassen verwendet, gibt das Framework die Struktur<br />

<strong>für</strong> die Anwendung vor [GHJV04]. Der Programmierer erstellt und registriert Klassen<br />

auf Grundlage <strong>der</strong> vorgegebenen Schnittstellen. So wird die konkrete Implementierung<br />

durch das Framework gesteuert und benutzt. Es wird zwischen programmiersprachen-<br />

und zweckabhängigen Frameworks differenziert. Beispiele <strong>für</strong> Frameworks sind<br />

Java EE, .NET und Spring.<br />

Für das Java-Framework Spring bildete das Buch „Expert One-On-One J2EE Design<br />

und Development“ die Grundlage <strong>für</strong> das OpenSource-Projekt Spring. Durch die große<br />

Resonanz und Beteiligung an dem OpenSource-Projekt wurde Spring stetig<br />

weiterentwickelt.<br />

Ziel dieser Arbeit ist die detaillierte Darstellung <strong>der</strong> Softwareentwicklung mit dem<br />

Spring Framework. Dazu wird zunächst im 2. Kapitel <strong>der</strong> Begriff Framework näher<br />

beleuchtet. Außerdem werden die Programmiertechniken Dependency Injection und<br />

Aspektorientierte Programmierung beschrieben. Diese sind von großer Bedeutung <strong>für</strong><br />

das Spring Framework, welches in Kapitel 3 vorgestellt wird. Anhand von Beispielen<br />

aus <strong>der</strong> Entwicklung einer Bibliotheksanwendung wird die Softwareentwicklung mit<br />

diesem Framework erläutert. Kapitel 4 vergleicht schließlich Spring mit dem Java EE<br />

Framework. Abschließend erfolgen in Kapitel 5 eine Zusammenfassung und ein<br />

Ausblick.<br />

1


Kapitel 2: Grundlagen<br />

2 Grundlagen<br />

2.1 Application Framework<br />

In <strong>der</strong> Literatur finden sich verschiedene Definitionen <strong>für</strong> den Begriff Framework. Eine<br />

Definition, die häufig verwendet wird, stammt von [GHJV04]:<br />

„Ein Framework ist eine Menge von kooperierenden Klassen, die einen<br />

wie<strong>der</strong>verwendbaren Entwurf <strong>für</strong> einen bestimmten Anwendungskontext<br />

vorgeben. Das Framework bestimmt dabei die Architektur <strong>der</strong> Applikation.“<br />

Ein Framework ist somit eine wie<strong>der</strong>verwendbare Umgebung <strong>für</strong> die<br />

Softwareentwicklung. Für die objektorientierte Programmierung bedeutet dies, dass ein<br />

bestimmtes Paket an Klassen zur Verfügung gestellt wird, um aus diesem<br />

Softwareanwendungen erstellen zu können. Das Framework gibt durch die verfügbaren<br />

Schnittstellen und abstrakte Klassen die grobe Anwendungsstruktur und den<br />

Kontrollfluss <strong>der</strong> Anwendung vor. Mit Hilfe dieser zur Verfügung gestellten Funktionen<br />

erstellt <strong>der</strong> Entwickler eine konkrete Anwendung. Da diese Funktionen nicht ohne<br />

Berücksichtigung eines konkreten Anwendungskontextes erstellt werden können, sind<br />

Frameworks meist domänenspezifisch. Um die Anwendungsarchitektur vorzugeben,<br />

findet eine Umkehrung des Kontrollflusses (Inversion of Control) statt. Dabei werden in<br />

<strong>der</strong> Erstellung einer Anwendung auf Basis eines Frameworks Klassen und Methoden<br />

aus dem Framework aufgerufen. Dieses Prinzip wird auch als Hollywood-Prinzip<br />

(„Don’t call us, we call you“) bezeichnet [GHJV04].<br />

Ein Vorteil von Frameworks ist, dass sie bereits fertig entworfene und implementierte<br />

Softwarestrukturen bereitstellen, die wie<strong>der</strong> verwendet werden können. So muss <strong>der</strong><br />

Entwickler z. B. Grundfunktionalitäten wie das Überprüfen von Benutzerrechten, die in<br />

je<strong>der</strong> Anwendung vorkommen, nicht jedesmal neu implementieren. Durch die<br />

Kapselung von Implementierungsdetails wird die Anwendung modularer und die<br />

Softwarequalität steigt. Ein weiterer Vorteil von Frameworks ist die Erweiterbarkeit.<br />

Das Framework stellt dem Entwickler feste Punkte bereit an denen er intervenieren und<br />

das Framework konfigurieren und erweitern kann [FaSc97].<br />

Bei Frameworks differenzieren [FaSc97] zwischen Black- und White-Box-Frameworks.<br />

Die Grundlage <strong>für</strong> White-Box-Frameworks bilden Vererbung und dynamisches Binden,<br />

um Erweiterbarkeit zu gewährleisten. Die bereitgestellte Funktionalität wird<br />

2


Kapitel 2: Grundlagen<br />

wie<strong>der</strong>verwendet und kann durch Vererbung <strong>der</strong> bereitgestellten Klassen o<strong>der</strong> durch<br />

Überschreiben von vordefinierten Methoden ergänzt werden. In Black-Box-<br />

Frameworks wird die Erweiterbarkeit durch Komposition in das Framework integriert,<br />

d. h. die zur Verfügung stehenden Komponenten müssen vom Entwickler konfiguriert<br />

und zusammengesetzt werden. Bei Black-Box-Framework kennt <strong>der</strong> Benutzer daher nur<br />

die Schnittstelle und nicht die innere Struktur. Im Gegensatz dazu muss <strong>der</strong> Benutzer<br />

des White-Box-Frameworks die innere Struktur des Frameworks genau kennen. Daher<br />

sind Black-Box-Framework leichter zu verwenden und erweitern als White-Box-<br />

Frameworks. Allerdings sind Black-Box-Frameworks schwieriger zu entwickeln, da<br />

hier Schnittstellen zur Verfügung gestellt werden müssen, die eine Reihe von<br />

potentiellen Anwendungsfällen abdecken [FaSc97].<br />

In dieser <strong>Ausarbeitung</strong> wird das Application Framework Spring vorgestellt. Dabei<br />

handelt es sich um eine Mischform aus Black- und White-Box-Framework, da es<br />

Vererbung und dynamisches Binden verwendet ebenso wie Komposition. Dazu werden<br />

die Programmiertechniken Dependency Injection und Aspektorientierte<br />

Programmierung benutzen.<br />

2.2 Dependency Injection<br />

Dependency Injection ist eine Programmiertechnik, die in <strong>der</strong> objektorientierten<br />

Programmierung eingesetzt wird, um die Abhängigkeiten zwischen Objekten zu<br />

minimieren. Solche Abhängigkeiten entstehen z. B. durch den Verweis eines Objekt auf<br />

ein an<strong>der</strong>es Objekt. Ohne die Anwendung von Dependency Injection ist jedes Objekt<br />

selbst <strong>für</strong> die Erzeugung und Verwaltung seiner Abhängigkeiten zuständig. Für die<br />

Erzeugung an<strong>der</strong>er Objekte muss das abhängige Objekt Getter- und Setter-Methoden<br />

<strong>für</strong> das zu erstellende Objekt zur Verfügung stellen. Bei Dependency Injection werden<br />

diese Abhängigkeiten verringert, indem die Verantwortung <strong>für</strong> die abhänigen Objekten<br />

an das Framework übergeben wird. Die Abhängigkeiten werden zur Laufzeit den<br />

Objekten injiziert. Dies wird meistens deklarativ in XML-Dateien konfiguriert.<br />

Außerdem lassen sich Klassen so einfacher testen, da ihre abhängigen Objekte durch<br />

Mock-Objekte ersetzt werden können. Mock-Objekte dienen als Platzhalter <strong>für</strong> echte<br />

Objekte innerhalb von Tests [Wo07].<br />

Es gibt drei Varianten von Dependency Injection: Interface-Injection, Setter-Injection<br />

und Constructor-Injection. Hierbei entsteht die größte Abhängigkeit bei Interface-<br />

3


Kapitel 2: Grundlagen<br />

Injection. Bei Interface-Injection muss eine Klasse alle Interfaces und <strong>der</strong>en<br />

vorgegebene Methoden implementieren damit alle abhängigen Objekte zugeordnet<br />

werden können. Es muss also <strong>für</strong> jede Art <strong>der</strong> Abhängigkeit eine Schnittstelle definiert<br />

werden. Um <strong>für</strong> Setter-Injection Abhängigkeiten zur Laufzeit erzeugen zu können, muss<br />

<strong>der</strong> Client die entsprechende Setter-Methode zum Setzen des benötigen Objektes<br />

anbieten. Bei Constructor-Injection werden sämtliche Abhängigkeiten einer Klasse über<br />

den Konstruktor übergeben. Damit kann ein Objekt <strong>der</strong> Klasse nur erzeugt werden,<br />

wenn alle Abhängigkeiten bei <strong>der</strong> Erstellung übergeben werden [Fo04].<br />

2.3 Aspektorientierte Programmierung<br />

Aspektorientierte Programmierung (AOP) ist ein Ansatz, um Codewie<strong>der</strong>holungen zu<br />

vermeiden. Dabei werden die sich ggf. wie<strong>der</strong>holenden Codestücke ausgelagert. Dies<br />

entspricht dem Prinzip „Separation of Concerns“. Das bedeutet <strong>der</strong> Basisbestandteil<br />

einer Methode wird von speziell zweckgebundenen und sich wie<strong>der</strong>holenden Teilen wie<br />

dem Überprüfen von Benutzerrechten getrennt. Die ausgelagerten Teile werden in <strong>der</strong><br />

AOP Aspekte bezeichnet. Ein Aspekt kann z. B. <strong>für</strong> Logging, Transaktionen o<strong>der</strong><br />

Sicherheit zuständig sein. Durch AOP entfällt die Duplizierung von Code. Er wird an<br />

einer zentralen Stelle implementiert und ist dadurch wie<strong>der</strong>verwendbar. Deshalb werden<br />

Aspekte auch als Querschnittsbelange (Cross Cutting Concerns) bezeichnet. Ein<br />

Beispiel hier<strong>für</strong> ist die Sicherheit, <strong>für</strong> die in je<strong>der</strong> Methode <strong>der</strong> Benutzer und seine<br />

Rechte überprüft werden. Mit AOP ist es möglich bei einem Methodenaufruf<br />

einzugreifen und zusätzlichen Code auszuführen. Die zentrale Speicherung des<br />

Quellcodes erhöht die Verständlichkeit und Wartbarkeit des Codes [Wo07].<br />

Im Umfeld von AOP werden neben dem Begriff Aspekt noch weitere Termini<br />

verwendet, die im Weiteren näher erläutert werden. Ein Advice beschreibt die Aufgabe<br />

eines Aspektes. Außerdem gibt <strong>der</strong> Advice an, wann die Aufgabe ausgeführt wird, z. B.<br />

vor dem Methodenaufruf. Stellen, an denen in <strong>der</strong> Anwendung ein Aspekt eingebunden<br />

werden kann, werden als Joinpoint bezeichnet. Ein Joinpoint kann z. B. vor einem<br />

Methodenaufruf o<strong>der</strong> bei einem geän<strong>der</strong>ten Feldwert auftreten. Pointcuts bilden eine<br />

Teilmenge <strong>der</strong> Joinpoints. Sie schränken die Aufrufe von Aspekten ein, indem sie<br />

definieren wo <strong>der</strong> Advice ausgeführt wird. Dies kann z. B. über reguläre Ausdrücke<br />

erfolgen. Ein Aspekt ist in diesem Zusammenhang die Vereinigung von Advice und<br />

Pointcut. Es ist bekannt welcher Code wo und wann ausgeführt wird [Wa08] .<br />

4


Kapitel 3: Spring Framework<br />

3 Spring Framework<br />

Bei Spring handelt es sich um ein OpenSource-Framework, welches insbeson<strong>der</strong>e die<br />

Programmierung von Java-EE-Anwendungen erleichtert. Grundlage <strong>für</strong> das Spring<br />

Framework bildete das Buch "Expert One-On-One J2EE Design and Development“. In<br />

diesem wurden die Programmiertechniken Dependency Injection und AOP beschrieben,<br />

die die wichtigsten Merkmale in Spring darstellen. Ziel <strong>der</strong> Entwicklung von Spring war<br />

es, die Erstellung von Unternehmensanwendungen zu vereinfachen. Die Basis <strong>für</strong> jede<br />

Spring-Anwendung bilden Anwendungsobjekte, sogenannte Spring-Beans, und <strong>der</strong><br />

Spring-Container, über den die Beans konfiguriert und über den kompletten<br />

Lebenszyklus verwaltet werden. Diese werden in den beiden folgenden Abschnitten<br />

näher beschrieben. Insgesamt setzt sich das Spring Framework aus sechs Modulen<br />

zusammen. Das Kernmodul stellt den Anwendungscontainer (Spring-Container) zur<br />

Verfügung, <strong>der</strong> die Grundlage <strong>für</strong> den Gebrauch von Dependency Injection bildet. Je<br />

nach Bedarf können weitere Spring Module an das Kernmodul angebunden werden, so<br />

dass die Nutzung von z. B. Hibernate ohne Probleme möglich ist. In den einzelnen<br />

Abschnitten dieses Kapitels werden außerdem noch die Module DAO und ORM, die <strong>für</strong><br />

den Datenbankzugriff notwendig sind und die Module AOP und MVC erläutert. Die<br />

Beschreibung von Spring und dessen Elementen erfolgt anhand eines Beispiels <strong>für</strong> die<br />

Implementierung einer Bibliotheksanwendung.<br />

3.1 Beispielanwendung Bibliothek<br />

Diese Beispielanwendung besteht aus Benutzern, die Exemplare von Büchern ausleihen<br />

können. Ein Klassendiagramm hierzu befindet sich im Anhang A. Es zeigt, dass Bücher<br />

eine 1:N-Beziehung zu Exemplaren haben, d. h. es kann mehrere Exemplare von einem<br />

Buch geben. Außerdem sind einem Benutzer mehrere Ausleihen zugeordnet. In diesem<br />

werden das Ausleihdatum, <strong>der</strong> Benutzer und das ausgeliehene Exemplar gespeichert.<br />

Ein Exemplar kann einer Ausleihe zugeordnet sein. Aus diesem Klassendiagramm wird<br />

mit Hilfe des Modules MVC eine Webanwendung erstellt. Mit dieser ist es möglich sich<br />

nach erfolgreichem Login alle Bücher sowie die aktuellen Ausleihen zu dem<br />

angemeldeten Benutzer anzeigen zu lassen. Der Administrator <strong>der</strong> Anwendung kann die<br />

Benutzer <strong>der</strong> Anwendung einsehen. In dieser Arbeit wird zunächst in Abschnitt 3.4<br />

Dependency Injection anhand <strong>der</strong> Klasse User erklärt. Diese wird in Abschnitt 3.7 um<br />

5


Kapitel 3: Spring Framework<br />

einen Datenbankzugriff erweitert. Die gesamten Daten <strong>der</strong> Anwendung sind in einer<br />

MySQL Datenbank gespeichert und werden über JDBC in die Anwendung integriert. In<br />

Abschnitt 3.5 wird AOP am Beispiel vom Logging-Aspekt erläutert. Das Module MVC<br />

wird in Abschnitt 3.6 anhand <strong>der</strong> Webseite zur Anzeige aller Bücher näher beschrieben.<br />

Damit sichergestellt ist, dass <strong>der</strong> authentifizierte Benutzer auch die erfor<strong>der</strong>lichen<br />

Rechte besitzt um bestimmte Services in Anspruch zu nehmen, wird in Abschnitt 3.8<br />

vorgestellt wie ein Sicherheitsaspekt mit Hilfe es Moduls Spring Security angelegt wird.<br />

3.2 Spring-Container<br />

Die Basis <strong>für</strong> jede Spring-Anwendung bilden Spring-Beans und <strong>der</strong> Spring-Container.<br />

Der Container erstellt, verbindet, konfiguriert und verwaltet alle Anwendungsobjekte,<br />

die Spring-Beans, über <strong>der</strong>en kompletten Lebenszyklus. Dazu wird Dependency<br />

Injection eingesetzt. Es gibt zwei Typen von Spring-Containern. Der Unterschied bei<strong>der</strong><br />

liegt im Leistungsumfang. Die BeanFactory ist eine Implementierung des Factory-<br />

Entwurfsmusters. Ihre Aufgabe ist es Spring-Beans zu erstellen und zu verteilen. Es<br />

handelt sich dabei um eine Allzweck-Factory, die unterschiedliche Bean-Typen<br />

zurückgibt. Die meistverwendete BeanFactory-Implementierung ist XmlBeanFactory.<br />

Sie arbeitet nach dem Lazy-Loading-Prinzip, d. h. die Instanzierung <strong>der</strong> Spring-Bean<br />

findet erst beim Aufruf <strong>der</strong> Bean durch die Methode getBean() statt. [Wa08, Kap. 2.1]<br />

Der ApplicationContext ist mächtiger als die BeanFactory. Deshalb wird dieser in<br />

komplexeren Anwendungen verwendet. Der Kontext umfasst neben den Funktionen <strong>der</strong><br />

BeanFactory Möglichkeiten zum Auslösen von Textnachrichten, Laden von<br />

Dateiressourcen wie Bil<strong>der</strong> und Veröffentlichen von Ereignissen <strong>für</strong> registrierte Spring-<br />

Beans. Im Gegensatz zur BeanFactory werden Singleton-Beans direkt instanziiert.<br />

BeanFactory factory = new XmlBeanFactory<br />

(new FileSystemResource("applicationContext.xml"));<br />

User peter = (User) factory.getBean("U4711");<br />

Listing 1: Erzeugung einer BeanFactory<br />

Ein Spring-Container kann aus je<strong>der</strong> normalen Java-Anwendung aufgerufen werden.<br />

Der Aufruf bei<strong>der</strong> Container-Typen ist ähnlich. Zunächst wird <strong>der</strong> Container erzeugt<br />

und anschließend die Bean über die Methode getBean() des Containers aufgerufen.<br />

Listing 1 zeigt die Erzeugung einer Spring-Bean über die BeanFactory. Dabei wird mit<br />

Hilfe einer FileSystemResource ein Objekt <strong>der</strong> XmlBeanFactory erzeugt. Die Bean-<br />

Definition wird aus einer XML-Datei ausgelesen. Üblicherweise wird eine Datei <strong>für</strong> die<br />

6


Kapitel 3: Spring Framework<br />

Konfiguration einer Spring-Anwendung erstellt. Aus dieser wird im Beispiel ein User-<br />

Bean, also <strong>der</strong> konkreter Benutzer Peter mit <strong>der</strong> ID U4711, über getBean() erzeugt<br />

[Wa08, Kap. 2.1].<br />

3.3 Spring-Bean<br />

Spring-Beans stellen Java-Klassen dar, die mit Hilfe des Spring-Containers konfiguriert<br />

werden. Für jedes Spring-Bean wird zunächst eine Java-Klasse mit setter- und getter-<br />

Methoden <strong>für</strong> die Attribute bzw. einem Konstruktor erstellt. Für die Injizierung erfolgt<br />

die Konfiguration über eine XML-Datei o<strong>der</strong> über Annotationen in <strong>der</strong> jeweiligen Java-<br />

Klasse. Bei XML-basierter Konfiguration wird eine Bean unter Verwendung des Tag<br />

erzeugt. Der Name über den auf das Bean über den Spring-Container<br />

zugegriffen werden kann, wird über das Attribut id übergeben. Im Attribut class wird<br />

<strong>der</strong> vollständige Name <strong>der</strong> Java-Klasse, auf den sich das Bean bezieht, angegeben<br />

[Wa08, Kap. 2.2].<br />

In Listing 2 wird eine Bean <strong>der</strong> Klasse User erzeugt. Auf dieses kann über die ID<br />

U4711 zugegriffen werden.<br />

Geltungsbereiche <strong>für</strong> Beans<br />

Jede Bean hat einen bestimmten Gültigkeitsbereich. Dieser wird über das Tag <br />

definiert. Dabei wird zwischen Singleton, Prototype, Request, Session und Global-<br />

Session differenziert. Standardmäßig sind alle Beans Singleton-Beans. Hierbei existiert<br />

nur eine Bean pro Spring-Container. Alle Aufrufe einer konkreten Bean werden von<br />

<strong>der</strong>selben Instanz durchgeführt. Mit Prototype ist eine mehrfache Instanziierung einer<br />

Bean ist möglich. Bei jedem Aufruf einer Bean wird eine neue Instanz erzeugt. Die<br />

Geltungsbereiche Request, Session und Global-Session finden nur im Rahmen von<br />

webbasierten Anwendungen Einsatz (z. B. bei Spring MVC) [Wa08, Kap. 2.5.1].<br />

3.4 Dependency Injection<br />

In Spring können zwei Typen von Dependency Injection eingesetzt werden: Setter-<br />

Injection und Konstruktor-Injection.<br />

7


Kapitel 3: Spring Framework<br />

Setter-Injection<br />

Bei Setter-Injection werden die Attribute <strong>der</strong> Bean über das -Tag gesetzt.<br />

Da<strong>für</strong> muss die Java-Klasse die entsprechenden Setter-Methoden aufweisen.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Listing 2: Setter-Injection<br />

Das Beispiel in Listing 2 zeigt, dass das -Tag die Attribute name und value<br />

besitzt. Mit name wird das Attribut <strong>der</strong> Bean-Klasse spezifiziert und mit value wird<br />

diesem eine Ausprägung übergeben. Hier wird ein Benutzer mit <strong>der</strong> ID 4711 und dem<br />

Namen Peter Muster erzeugt. Dies ist ein Beispiel ohne die Verwendung einer<br />

Datenbank. Auf die Verwendung einer Datenbank wird in Kapitel 3.7 näher<br />

eingegangen [Wa08, Kap. 2.3].<br />

Constructor-Injection<br />

Wenn die Injektion über einen Konstruktor erfolgen soll, passiert dies mit dem Tag<br />

. Über das Attribut value wird <strong>der</strong> Wert <strong>für</strong> den ersten<br />

Konstruktorwert übergeben. Durch Wie<strong>der</strong>holung des -Tags können<br />

bei mehreren Parametern im Konstruktor diesem Werte übergeben werden [Wa08,<br />

Kap. 2.2.2].<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Listing 3: Konstruktor-Injektion<br />

In Listing 3 wird <strong>der</strong> gleiche Benutzer wie in Listing 2 erzeugt. In diesem Fall<br />

allerdings durch Übergabe <strong>der</strong> Attributwerte an den Konstruktor.<br />

Die Beispiele zeigen, dass dem Attribut value immer Strings übergeben werden. Intern<br />

wird dieser String auf den entsprechenden Datentyp des Klassenattributes gecastet. Das<br />

Attribut value kann nur <strong>für</strong> primitive Datentypen und <strong>der</strong>en entsprechende Wrapper-<br />

8


Kapitel 3: Spring Framework<br />

Klassen verwendet werden. Falls auf eine an<strong>der</strong>e Bean referenziert werden soll, ist<br />

hier<strong>für</strong> das Attribut ref zu verwenden.<br />

Collections verschachteln<br />

Falls eine Bean eine Eigenschaft, die eine Liste von Ausprägungen wie eine Collection<br />

besitzt, kann diese auf vier unterschiedliche Arten mit Spring konfiguriert werden. Die<br />

Tags und verschachteln eine Liste von Werten, wobei nur bei <br />

doppelte Werte erlaubt sind. Die dritte Möglichkeit Mehrfacheigenschaften zu<br />

konfigurieren ist über das -Tag. Diese entspricht <strong>der</strong> Collection java.util.Map.<br />

Das -Tag stellt die vierte Möglichkeit zur Konfiguration von<br />

Mehrfacheigenschaften dar und entspricht java.util.Properties [Wa08, Kap. 2.3].<br />

<br />

. . .<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Listing 4: Injizierung von Collections<br />

In Listing 4 wird über das Tag eine Collection <strong>für</strong> das Attribut lending zum<br />

Benutzer U4711 angelegt d. h. <strong>der</strong> Benutzer hat zur Zeit drei Exemplare ausgeliehen.<br />

Autowiring<br />

Statt alle Eigenschaften einer Bean über die Tags o<strong>der</strong> zu<br />

setzen, kann vor allem bei komplexen Anwendungen, die Verknüpfung <strong>der</strong> Beans<br />

untereinan<strong>der</strong> automatisch erfolgen. Dabei wird bei jedem Bean, das automatisch<br />

verbunden werden soll, die Eigenschaft autowire gesetzt. In Spring gibt es vier Typen<br />

von Autowiring. Bei Autowiring byName wird die Eigenschaft von Beans über den<br />

Namen <strong>der</strong> Eigenschaft vervollständigt. Lautet <strong>der</strong> Name <strong>der</strong> Eigenschaft z. B. „book“<br />

wird nach einem Bean mit <strong>der</strong> id „book“ gesucht. Die Vervollständigung kann auch<br />

über den Typ <strong>der</strong> Eigenschaft, also dem Klassennamen z. B. class = bib.User, erfolgen.<br />

Dies wird als Autowiring byType bezeichnet. Die dritte Variante von Autowiring ist<br />

byConstructor. Dabei wird versucht eine o<strong>der</strong> mehrere Beans auf die Parameter des<br />

Konstruktors abzubilden. Bei <strong>der</strong> vierten Variante, Autodect-Autowiring, wird<br />

Autowiring erst byType und anschließend byConstructor durchgeführt. Das<br />

9


Kapitel 3: Spring Framework<br />

automatische Verbinden aller Eigenschaften einer Bean, kann durch Angabe von<br />

Eigenschaften über das Tag überschrieben werden [Wa08, Kap. 2.4].<br />

3.5 Aspektorientierte Programmierung<br />

Vom Spring Framework werden in <strong>der</strong> AOP nur Joinpoints im Zusammenhang mit<br />

einem Methodenaufruf unterstützt. An<strong>der</strong>e AOP Funktionalitäten können über die<br />

Einbindung von <strong>der</strong> Java-AOP-Erweiterung AspectJ in das Spring Framework erzielt<br />

werden. Spring-Advices sind in Java-Klassen zu erstellen. Die dazugehörigen Pointcuts<br />

werden gewöhnlich in <strong>der</strong> XML-Konfigurationsdatei geschrieben. Aspekte werden in<br />

Spring zur Laufzeit in Spring-Beans eingebettet, indem sie in einer Proxy-Klasse<br />

gekapselt werden. Der Proxy fängt den Methodenaufruf ab, so dass die Methode um die<br />

Zusatzfunktionalität, den Advice, erweitert werden kann. Der Proxy wird ebenfalls in<br />

<strong>der</strong> Bean-Konfigurationsdatei definiert. Bei Spring AOP gibt es fünf verschiedene<br />

Typen von Advices, die über Einbindung des entsprechenden Interfaces implementiert<br />

werden. Dabei werden die Interfaces MethodBeforeAdvice, AfterReturningAdvice,<br />

ThrowsAdvice, MethodInterceptor und IntroductionInterceptor unterschieden [Wa08,<br />

Kap. 4.1].<br />

package aop;<br />

public class LoggingAdvice implements MethodInterceptor {<br />

public Object invoke(MethodInvocation methodInvocation){<br />

Log log;<br />

log = LogFactory.getLog(getClassName(methodInvocation));<br />

log.info("Class : " + getClassName(methodInvocation));<br />

log.info("Method : " + getMethodName(methodInvocation));<br />

log.info("Arguments : " + getArguments(methodInvocation));<br />

...<br />

//ausführen <strong>der</strong> eigentlichen Methode<br />

result = methodInvocation.proceed();<br />

...<br />

}<br />

...<br />

}<br />

Listing 5: LoggingAdvice<br />

Listing 5 zeigt ein typisches Beispiel <strong>für</strong> einen Advice, den LoggingAdvice. Hiermit<br />

werden zu je<strong>der</strong> Methode, die dem Advice zugeordnet wird, Logginginformationen wie<br />

die aufgerufene Methode und <strong>der</strong>en übergebene Parameter auf <strong>der</strong> Konsole ausgegeben.<br />

Dazu wird das Interface MethodInterceptor implementiert, das die Methode invoke()<br />

beinhaltet, die implementiert werden muss. Über methodeInvocation.proceed() wird die<br />

abgefangene Methode ausgeführt.<br />

10


Kapitel 3: Spring Framework<br />

Anschließend werden Pointcuts in <strong>der</strong> Konfigurationsdatei definiert. In Spring werden<br />

Pointcuts am häufigsten über reguläre Ausdrücke o<strong>der</strong> mit AspectJ-Ausdrücken<br />

festgelegt. Der reguläre Ausdruck legt fest, in welchen Methoden <strong>der</strong> zum Pointcut<br />

gehörende Advice ausgeführt wird. Dies erfolgt über einen Vergleich zwischen dem<br />

regulären Ausdruck und <strong>der</strong> Methodensignatur. In <strong>der</strong> XML-Konfigurationsdatei wird<br />

über das Attribut pattern <strong>der</strong> reguläre Ausdruck angegeben [Wa08, Kap. 4.1].<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Listing 6: Konfiguration von Advice, Pointcut und Advisor<br />

In Listing 6 ist <strong>der</strong> Pointcut loggingPointcut definiert, <strong>der</strong> <strong>für</strong> jede Methode in Package<br />

services angewandt wird. Neben dem Pointcut ist noch die Verschmelzung mit dem<br />

Advice zu konfigurieren. Dieser Aspekt wird in Spring als Advisor gehandhabt. Über<br />

die -Tags des Advisor werden <strong>der</strong> Pointcut und Advice in Listing 6 vereinigt.<br />

3.6 Model View Controller<br />

Für den Aufbau einer webbasierten Anwendung wird in Spring das Modul MVC<br />

eingesetzt. Dieses beruht auf dem Entwurfsmuster Model View Controller (MVC).<br />

Stellt ein Benutzer eine Anfrage, wenn er z. B. alle Bücher <strong>der</strong> Bibliothek einsehen<br />

möchte, wird diese in Spring zunächst an das Dispatcher Servlet gesendet, welcher auch<br />

als Frontend-Controller bezeichnet wird. Dieser agiert, wie <strong>der</strong> Begriff schon vermuten<br />

lässt, als Verteiler von Aufgaben. Diese Weitergabe und Entgegennahme <strong>der</strong> Ergebnisse<br />

visualisiert Abbildung 1.<br />

11


Kapitel 3: Spring Framework<br />

Abbildung 1: Anfrageverarbeitung über Dispatcher Servlet<br />

Wie jedes Servlet muss auch <strong>der</strong> Dispatcher in <strong>der</strong> web.xml-Datei deklariert werden.<br />

Über das -Tag wird angegeben, welche URLs das Servlet behandeln soll.<br />

Die Webanfragen behandelt ein Controller im Auftrag des Dispatcher Servlets (siehe<br />

Nr. 3 in Abbildung 1). Zur Abwicklung <strong>der</strong> Anfrage verteilt dieser die Aufgaben an die<br />

Serviceschicht und führt die übermittelten Ergebnisse anschließend zusammen. Der<br />

Controller wird als normale Java-Klasse implementiert und im Anwendungskontext als<br />

Bean konfiguriert. Für die vorgestellte Bibliotheksanwendung wird eine Webseite<br />

benötigt, die alle vorhandenen Bücher anzeigt. Der BookController in Listing 7 erbt von<br />

<strong>der</strong> Klasse AbstractController. Darin wird die Methode handleRequestInternal()<br />

implementiert. In dieser wird die Methode getBooks() des BookService aufgerufen und<br />

ein ModelAndView-Objekt zurückgeben [Wa08 , Kap. 13.1].<br />

package mvc;<br />

public class BookController extends AbstractController{<br />

private BookService bookService;<br />

private String view = "booklist";<br />

public BookService getBookService() {<br />

return bookService;<br />

}<br />

public void setBookService(BookService bookService) {<br />

this.bookService = bookService;<br />

}<br />

protected ModelAndView handleRequestInternal(HttpServletRequest<br />

request, HttpServletResponse response) throws Exception {<br />

Map model = new HashMap();<br />

model.put("books", bookService.getBooks());<br />

return new ModelAndView(view, model);<br />

}<br />

<br />

<br />

<br />

Listing 7: Implementierung und Konfiguration eines Controllers<br />

12


Kapitel 3: Spring Framework<br />

Des Weiteren wird <strong>der</strong> BookController in Listing 7 als Bean konfiguriert. Im Bean wird<br />

anstelle des Attributes id unter name die URL des Controllers mit vorausgesetztem<br />

Schrägstrich angegeben z. B. /book.htm. So wird jede Anfrage, die mit dieser URL an<br />

das Dispatcher Servlet gestellt wird, an diesen Controller weitergegeben. Anstelle <strong>der</strong><br />

Verwendung <strong>der</strong> name-Eigenschaft, könnte auch ein Handler-Mapping-Bean<br />

konfiguriert werden (siehe Nr. 2 in Abbildung 1). Ein Handler-Mapping-Bean<br />

entscheidet, welcher Controller die Anfrage bearbeitet. Im Controller-Bean wird <strong>der</strong><br />

Service, <strong>der</strong> Aufgaben ausführen soll, über Dependency Injection injiziert. Im Beispiel<br />

ist das BookService. Die Methode handleRequestInternal() zur Behandlung <strong>der</strong> Anfrage<br />

muss ein Objekt <strong>der</strong> Klasse ModelAndView zurückgeben. Dieses Objekt kapselt die<br />

View und die Modelldaten, die vom View dargestellt werden sollen. Das<br />

ModelAndView-Objekt wird vom Dispatcher Servlet an den View-Resolver weiter<br />

gegeben (siehe Nr. 5 in Abbildung 1). Der ordnet dem im ModelAndView-Objekt<br />

zurückgegebenen View-Namen eine View zu. Die View ist in den meisten Fällen eine<br />

JSP-Seite z. B. booklist.jsp. Listing 8 zeigt wie <strong>der</strong> View-Resolver über den<br />

Anwendungskontext zu konfigurieren ist. Dabei wird <strong>für</strong> JSP-Seiten<br />

InternalResourceViewResolver verwendet. Mit ihm können über die Attribute prefix<br />

und suffix an den View-Namen Werte vor- bzw. angehangen werden, so dass sich eine<br />

vollständige URL ergibt. Für das Beispiel in Listing 8 ergibt sich die URL „/WEB-<br />

INF/jsp/booklist.jsp“. An diese URL leitet das Dispatcher Servlet die Anfrage weiter,<br />

um die Webseite <strong>für</strong> den Benutzer dazustellen. Die JSP-Seite die dabei aufgerufen wird<br />

findet sich in Listing 9. In <strong>der</strong> JSP-Seite wird dabei auf das Model „books“<br />

zurückgegriffen. Somit bekommt <strong>der</strong> Benutzer eine Liste mit allen Büchern angezeigt<br />

[Wa08 , Kap. 13.1].<br />

<br />

<br />

<br />

<br />

Listing 8: Konfiguration eines View-Resolvers<br />

<br />

<br />

<br />

<br />

<br />

<br />

Bücherliste<br />

13


Kapitel 3: Spring Framework<br />

<br />

<br />

Willkommen in <strong>der</strong> Bibliothek<br />

Hier sehen Sie alle verfügbaren Bücher<br />

<br />

BuchAutor<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Listing 9: View books.jsp<br />

3.7 Datenbankzugriff<br />

Für eine praktische Verwendung benötigt fast jede Anwendung eine Datenpersistenz.<br />

Spring integriert eine ganze Reihe an Datenzugriffs-Frameworks, die mit vielen<br />

Datenzugriffstechnologien verbunden werden können. Dies sind u. a. JDBC o<strong>der</strong> O/R<br />

Mapper wie Hibernate, iBATIS o<strong>der</strong> JPA. In diesem Unterkapitel wird die Anbindung<br />

von JDBC und als Beispiel <strong>für</strong> einen O/R Mapper JPA vorgestellt.<br />

Data Access Objects (DAO) kapseln den Datenbankzugriff in Spring. Dies geschieht<br />

unter Verwendung des Entwurfsmusters <strong>der</strong> Schablonenmethode (Template Method).<br />

Die generelle Struktur eines Datenzugriffs wird unabhängig von <strong>der</strong> verwendeten<br />

Technologie in einer abstrakten Oberklasse (Template) definiert. Bestimmte<br />

Operationen des Datenbankzugriffs können in den Unterklassen überschrieben werden,<br />

ohne die Struktur des Zugriffs zu än<strong>der</strong>n. Zu den feststehenden Teilen des Zugriffs<br />

zählen die Steuerung von Transaktionen, die Ressourcenverwaltung und die<br />

Exceptionbehandlung. Des Weiteren bietet Spring noch Supportklassen zur<br />

Vereinfachung des Zugriffs auf das Template. Den Zusammenhang zeigt Abbildung 2<br />

[Wa08, Kap. 5.1].<br />

Abbildung 2: Beziehung zwischen Anwendungs-DAO, DAO-Supportklasse und Schablonenklasse<br />

[Wa08, Kap. 5.1]<br />

14


Kapitel 3: Spring Framework<br />

Diese Implementierung trennt die Datenzugriffschicht in Spring vom Rest <strong>der</strong><br />

Anwendung. Dies hat zur Folge, dass eine konsistente Exception-Hierarchie über alle<br />

DAO-Frameworks hinweg verfügbar ist. Es werden nicht die Exceptions aus JDBC<br />

o<strong>der</strong> an<strong>der</strong>en OR-Mappern in das Spring Framework übernommen, da JDBC<br />

Exceptions universell sind und Exceptions von OR-Mapper spezifisch auf die<br />

Datenbank bzw. das Framework zu geschnitten sind. Diese Exception werden<br />

abgefangen und intern verarbeitet. Zurückgegeben werden Spring eigene Exceptions,<br />

die von RuntimeException abgeleitet sind. Für diese ist keine Behandlung notwendig.<br />

So kann sich <strong>der</strong> Programmierer den catch-Block sparen [Wa08, Kap. 5.1].<br />

JDBC-Anbindung<br />

Grundlage <strong>für</strong> den Datenbankzugriff ist die Definition eines Datenquellen-Beans<br />

DataSource. Da<strong>für</strong> stehen in Spring zwei Klassen zur Verfügung.<br />

DriverManagerDataSource gibt bei je<strong>der</strong> Anfrage eine neue Verbindung zurück,<br />

während SingleConnectionDataSource immer dieselbe Verbindung wie<strong>der</strong>gibt. Da<br />

beide Verbindungen über keinen Pool zur Verbindungsverwaltung verfügen, sind sie <strong>für</strong><br />

komplexere Anwendungen nicht geeignet. Das Beispiel in Listing 10 zeigt wie das<br />

dataSource-Bean konfiguriert wird. Das Attribut driverClassName enthält den JDBC-<br />

Datendatenbanktreiber, url die Adresse <strong>der</strong> verwendete Datenbank und username und<br />

password den zugehörigen Benutzer und das Kennwort [Wa08, Kap. 5.3].<br />

<br />

<br />

<br />

<br />

<br />

<br />

Listing 10: JDBC Anbindung<br />

Anschließend ist ein AnwendungsDAO zu erstellen. Da<strong>für</strong> wird zunächst eine DAO-<br />

Klasse implementiert. Diese kann von <strong>der</strong> von Spring bereitgestellten Supportklasse <strong>für</strong><br />

JDBC-Datenbanken NamedParameterJdbcDaoSupport abgeleitet werden. Mit dieser<br />

Klasse ist neben <strong>der</strong> Bereitstellung von Standard-JDBC-Funktionen in SQL-Statements<br />

die Verwendung von benannten Parametern anstatt von indizierten Parametern möglich.<br />

Da<strong>für</strong> werden <strong>der</strong> Methode zur Ausführung eines SQL-Statements das Statement und<br />

eine HashMap mit den Parametern des Statements übergeben. Listing 11 zeigt dies am<br />

15


Kapitel 3: Spring Framework<br />

Beispiel <strong>für</strong> das Auslesen aller Bücher <strong>für</strong> die Bibliotheksanwendung. Diese werden mit<br />

Hilfe eines RowMappers in einer Liste von Büchern konvertiert [Wa08, Kap. 5.3].<br />

package jdbc;<br />

public class BookDAO extends NamedParameterJdbcDaoSupport implements<br />

IBookDao{<br />

public List getAll() {<br />

return (List) getJdbcTemplate().query(<br />

"SELECT DESCRIPTION, ISBN, AUTOR, ID FROM Book ",<br />

new BookRowMapper());<br />

}<br />

… }<br />

Listing 11: JDBC Anfrage<br />

JPA-Anbindung<br />

Die JPA-Anbindung erfolgt sowohl in JPA direkt als auch in Spring über einen Entity-<br />

Manager. Des Weiteren wird <strong>für</strong> die JPA-Anbindung wie<strong>der</strong> mit einem Template<br />

gearbeitet (siehe Listing 12). Das JpaTemplate erfüllt die gleichen Aufgaben wie an<strong>der</strong>e<br />

Templates <strong>für</strong> Datenbankanbindungen in Spring auch. Zudem sorgt es da<strong>für</strong>, dass <strong>der</strong><br />

Entity-Manager wie benötigt geschlossen und geöffnet wird und stellt weitestgehend<br />

dieselben Persistenzmethoden wie ein Entity-Manager <strong>für</strong> JPA zur Verfügung [Wa08,<br />

Kap. 5.5].<br />

Als Entity-Manager kann ein anwendungsverwalten<strong>der</strong> o<strong>der</strong> containerverwalten<strong>der</strong><br />

Entity-Manager eingesetzt werden. Der Unterschied zwischen beiden liegt in <strong>der</strong><br />

Konfiguration. Diese erfolgt <strong>für</strong> anwendungsverwaltende Entity-Manager über eine<br />

Konfigurationsdatei namens persistenxe.xml, bei containerverwalten<strong>der</strong> Konfiguration<br />

im Spring-Anwendungskontext. Listing 12 zeigt wie ein containterverwalten<strong>der</strong> Entity-<br />

Manager in Spring mithilfe von LocalContainerEntityManagerFactoryBean<br />

konfiguriert wird.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

16


Kapitel 3: Spring Framework<br />

<br />

Listing 12: Konfiguration einer containerverwaltenden EntityManagerFactory-Bean<br />

Die Konfiguration <strong>der</strong> Datenquelle, welche vom Entity-Manager benutzt wird, erfolgt<br />

über die Eigenschaft dataSource und ist vergleichbar mit <strong>der</strong> Konfiguration in Listing<br />

10. Über die Eigenschaft jpaVendorAdapter können Details zur verwendeten JPA-<br />

Implementierung angeführt werden. In diesem Fall ist das TopLink Essentials.<br />

Nach <strong>der</strong> Konfiguration des Entity-Managers wird die DAO-Klasse eingerichtet. Wie<br />

bereits bemerkt, bietet Spring da<strong>für</strong> Support-Klassen an, von denen die selbst zu<br />

erstellende DAO-Klasse erbt. Für die JPA-Anbindung wird JpaDaoSupport verwendet.<br />

Diese Verwendung zeigt Listing 13 am Beispiel <strong>der</strong> Klasse JpaUserDAO. Für die<br />

dauerhafte Speicherung eines Objekts in <strong>der</strong> Datenbank muss die Methode persist des<br />

JpaTemplate Objekts aufgerufen werden [Wa08, Kap. 5.5].<br />

public class JpaUserDAO extends JpaDaoSupport implements IUserDAO {<br />

public void createUser(User user) throws CreateFailureException<br />

{<br />

getJpaTemplate().persist(user);<br />

}<br />

}<br />

Listing 13: Klasse JpaUserDAO<br />

3.8 Sicherheit<br />

Das Sicherheits-Framework in Spring stellt umfangreiche Sicherheitslösungen <strong>für</strong> die<br />

Authentifizierung und Autorisierung auf Webanfrage- und Methodenaufrufebene zur<br />

Verfügung. Spring Security nutzt da<strong>für</strong> DI und AOP. Mit Hilfe des Authentification-<br />

Managers erfolgt die Überprüfung des Benutzernamens und des dazugehörigen<br />

Passworts. Nach erfolgreicher Authentifizierung wird über den Access-Decision-<br />

Manager kontrolliert, ob die Anfrage o<strong>der</strong> Methode von Benutzer ausgeführt werden<br />

darf [Wa08, Kap. 7.1].<br />

Authentifizierung<br />

Der Authentication-Manager verifiziert die eingegebenen Benutzerdaten über die<br />

Methode authenticate(). Bei erfolgreicher Authentifizierung gibt die Methode ein<br />

Authentication-Objekt zurück, das Information über den Benutzer und dessen Rechte<br />

enthält. An<strong>der</strong>nfalls wird eine AuthenticationException ausgelöst. Für die meisten Fälle<br />

<strong>der</strong> Benutzerprüfung wird <strong>der</strong> Provi<strong>der</strong>Manager, eine Implementierung des<br />

17


Kapitel 3: Spring Framework<br />

AuthenticationManager, benutzt. Dabei kann <strong>der</strong> Benutzer gegenüber mehreren Quellen<br />

zur Identitätsverwaltung authentifiziert werden. Dazu werden die Benutzereingaben an<br />

Provi<strong>der</strong> weitergegeben. Der Provi<strong>der</strong>Manager erhält im Attribut provi<strong>der</strong> eine Liste <strong>der</strong><br />

Authentifizierungsdienste. Im Allgemeinen wird nur ein Dienst benötigt. Für die<br />

Authentifizierung mit Hilfe einer Datenbank bietet Spring Security den<br />

DaoAuthenticationProvi<strong>der</strong>. Die Konfiguration des Provi<strong>der</strong>Managers findet sich im<br />

oberen Teil von Listing 14. Dieser kann über die authenticationManager referenziert<br />

werden und beinhaltet einen AuthenticationProvi<strong>der</strong>, <strong>der</strong> weiter unten definiert ist<br />

[Wa08, Kap. 7.2].<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

SELECT USERNAME, PASSWORD, ENABLE as enabled<br />

FROM USER<br />

WHERE USERNAME = ?<br />

<br />

<br />

<br />

<br />

SELECT u.USERNAME as username, AUTORITY as authority<br />

FROM AUTORITY a , USER u<br />

WHERE a.USERNAME = u.USERNAME<br />

AND u.USERNAME = ?<br />

<br />

<br />

<br />

Listing 14: Konfiguration des Authentification Managers<br />

Des Weiteren wird in Listing 14 das AuthenticationDAO konfiguriert, das eine<br />

Instanzierung von JdbcDaoImpl ist. Diese erwartet, dass die Benutzerangaben in den<br />

Tabellen Users und Authorities mit den Attributen username, password und enabled<br />

bzw. username und authority vorliegt. Falls dies nicht <strong>der</strong> Fall ist, können wie in Listing<br />

18


Kapitel 3: Spring Framework<br />

14 über die Eigenschaften usersByUsernameQuery und authoritiesByUsernameQuery<br />

die entsprechenden SQL-Statements angegeben werden.<br />

Autorisierung<br />

Als nächster Schritt nach <strong>der</strong> Authentifizierung erfolgt die Autorisierung. Da<strong>für</strong> wird<br />

zunächst festgelegt, wie die Entscheidung <strong>für</strong> den Zugriff auf das angefragte Objekt<br />

getroffen werden soll. Es gibt dazu drei Implementierungen des<br />

AccessDecisionManager. Die Konfiguration <strong>für</strong> alle ist gleich.<br />

Listing 15 zeigt den Typ UnianimousBased, <strong>der</strong> den Zugriff gewährt, wenn alle<br />

Abstimmenden <strong>für</strong> den Zugriff gestimmt haben. Als nächstes werden eine o<strong>der</strong> mehrere<br />

Instanzen konfiguriert, welche kontrollieren, ob die Benutzerrechte mit den Rechten, die<br />

<strong>für</strong> den Zugriff auf das Objekt benötigt werden, übereinstimmen. Jede Instanz<br />

implementiert dabei das Interface AccessDecisionVoter. In<br />

Listing 15 wird eine Instanz roleVoter konfiguriert. Diese stimmt <strong>für</strong> den Zugriff, wenn<br />

<strong>der</strong> Benutzer zur Rolle mit dem Präfix „ROLE_“ gehört [Wa08, Kap. 7.3].<br />

Weitere Möglichkeiten, die <strong>der</strong> Authentication-Manager bietet sind Passwort-<br />

Verschlüsselung, Caching von Benutzerdaten und Authentifizierung gegenüber LDAP<br />

[Wa08, Kap. 7.2].<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Listing 15: Konfiguration des AccessDecisionManagers<br />

Zuordnung zu Methoden<br />

<br />

<br />

<br />

<br />

19


Kapitel 3: Spring Framework<br />

<br />

<br />

<br />

<br />

services.BookService.getBooks*=ROLE_USER<br />

services.LendingService.getLendings*=ROLE_USER<br />

services.UserService.getUsers*=ROLE_ADMIN<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

securityInterceptor<br />

<br />

<br />

<br />

<br />

services.BookService<br />

services.LendingService<br />

services.UserService<br />

<br />

<br />

<br />

Listing 16: Zuordnung und Konfiguration von Zugriffrechten zu Methoden<br />

Listing 16 zeigt wie Zugriffsrechte <strong>für</strong> Methoden vergeben werden. Dazu wird ein<br />

securityInterceptor konfiguriert, dem <strong>der</strong> AuthenticationManager und<br />

AccessDecisionManager zugeordnet wird. Über die Eigenschaft objectDefinitionSource<br />

werden einzelnen Methoden Rollen zugeordnet, z. B. darf nur <strong>der</strong> Admin die Methode<br />

getUsers() aufrufen und damit alle Benutzer einsehen. Außerdem dürfen Benutzer mit<br />

<strong>der</strong> Rolle ROLE_USER Bücher und Ausleihen aufrufen ebenso wie <strong>der</strong> Admin. Neben<br />

<strong>der</strong> Zugriffrechtezuordnung muss zudem ein Proxy <strong>für</strong> den securityInterceptor definiert<br />

werden. Somit werden bei Aufruf <strong>der</strong> Beans BookService, LendingService und<br />

UserService zunächst über den Proxy die Zugriffsrechte des Benutzers überprüft. Hier<br />

findet also AOP ihre Anwendung. Wenn <strong>der</strong> Benutzer nicht authentifiziert ist, wird eine<br />

AuthentificationException ausgelöst. Eine AccessDecisionException wird geworfen,<br />

wenn <strong>der</strong> Benutzer nicht die erfor<strong>der</strong>lichen Rechte aufweist [Wa08, Kap. 7.6].<br />

20


Kapitel 4: Vergleich Spring und Java EE<br />

4 Vergleich Spring und Java EE<br />

Spring ist entstanden, um die Entwicklung von Java EE-Anwendungen zu vereinfachen<br />

ohne auf Vorteile <strong>der</strong> Java-EE-Umgebung verzichten zu müssen. Aus diesem Grund<br />

wird es auch als Lightweight-Framework bezeichnet. Dieses leichtgewichtige Modell<br />

baut auf POJOs (Plain Old Java Objects) auf, also auf „ganz normalen“ Objekten.<br />

Dennoch verlangt auch Spring eine gründliche Auseinan<strong>der</strong>setzung mit dem Framework<br />

damit diese angewandt werden kann. Java EE ist neben seiner Komplexität auch sehr<br />

flexibel. Deshalb werden größere Anwendungen in Java EE implementiert. Mittlerweile<br />

unterstützt auch Java EE durch die Spezifikation EJB 3.0 ein POJO-basiertes<br />

Programmiermodell, das die Anwendung schlichter macht [Wo07, Kap. 1.3].<br />

Java EE und Spring nutzen beide Dependency Injection. In Spring erfolgt die<br />

Konfiguration meistens über Deskriptoren also XML. Dahingegen werden in Java EE<br />

meistens Annotationen verwendet. Deskriptoren können aber <strong>für</strong> das Überschreiben von<br />

Methoden verwendet werden. Ebenso ist es in Spring möglich Annotationen zu<br />

benutzen. Java EE verwendet <strong>für</strong> die Geschäftslogik EJBs, die nur zusammen mit einem<br />

Java-Server lauffähig sind. In Spring wird die Geschäftslogik unabhängig vom Server<br />

verwaltet. Ein weiteres Ziel von Spring ist die Integration an<strong>der</strong>er Frameworks zu<br />

vereinfachen [Wo07, Kap 1.3].<br />

Das Interceptor-Konzept <strong>für</strong> EJB 3.0 erlaubt die Behandlung von Querschnittsbelangen<br />

wie Sicherheitsaspekten. Dies ist die erste und einfache Form von AOP in einer Java-<br />

EE-Anwendung. In Spring stellt AOP einer Grundfunktionalität dar. Dabei werden<br />

Methoden Pointcuts unterstützt. Für einen größeren Funktionsumfang kann AspectJ in<br />

Spring eingebunden werden. Somit bietet Spring eine umfangreichere AOP Umsetzung<br />

als Java EE an [Wo07, Kap 1.3].<br />

Bei Java EE handelt es sich um einen Standard. Dies hat zum Vorteil, dass<br />

Herstellerunabhängigkeit erreicht wird. Des Weiteren ist viel Wissen über Java EE auf<br />

dem Markt verfügbar. Das reduziert den Einarbeitungsaufwand und es können schneller<br />

Lösungen <strong>für</strong> Probleme gefunden werden. Diese Vorteile können auch in einem Spring<br />

Projekt genutzt werden. Dazu muss Spring als Abstraktion über eine Java-EE-<br />

Umgebung verwendet werden [Wo07, Kap 1.3].<br />

21


Kapitel 5: Zusammenfassung und Ausblick<br />

5 Zusammenfassung und Ausblick<br />

In dieser Arbeit wurde zunächst <strong>der</strong> Begriff Framework näher erläutert. Dabei handelt<br />

es sich um ein Rahmenwerk, das <strong>für</strong> die Softwareentwicklung bestimmte<br />

Funktionalitäten zur Verfügung stellt. Diese können genutzt und erweitert werden. So<br />

wird vermieden, dass wie<strong>der</strong> verwendbare Funktionalitäten jedes Mal neu<br />

implementiert werden müssen.<br />

Anschließend wurden die Programmiertechniken Dependency Injektion und<br />

Aspektorientierte Programmierung erläutert. Dieses sind die wichtigsten<br />

Programmiertechniken, die im Spring Framework verwendet werden. In Kapitel 3<br />

wurde dieses Framework anhand einer Bibliotheksanwendung näher dargelegt. Dabei<br />

wurden zunächst Spring-Beans und <strong>der</strong> Spring-Container anhand von Beispielen<br />

veranschaulicht. Spring-Beans stellen Anwendungsobjekte dar, die über eine<br />

Konfigurationsdatei erstellt und über den Spring-Container verwaltet werden. Im<br />

Anschluss daran wurden Dependency Injektion und AOP in Spring vorgestellt. In<br />

Spring können die Typen Setter- und Constructor-Injektion verwendet werden.<br />

Nachfolgend wurde die Konfiguration einer Datenbankanbindung über JDBC und JPA<br />

beschrieben. Außerdem wird <strong>für</strong> die Gewährleistung <strong>der</strong> Sicherheit im System eine<br />

verlässige Authentifizierung von Benutzer benötigt. Dazu werden in Spring auch<br />

Aspekte eingesetzt.<br />

Nach <strong>der</strong>en Vorstellung, schließt die Arbeit mit einem Vergleich zwischen den<br />

Frameworks Spring und Java EE. Dabei wurden herausgestellt, dass Spring als<br />

leichtgewichtige Entwicklung zu Java EE entwickelt wurde. Mittlerweile ist in Java EE<br />

durch die Spezifikation EJB 3.0 die Java-Entwicklung einfacher. In beiden Frameworks<br />

kann Dependency Injection und AOP eingesetzt werden.<br />

In dieser Arbeit wurden einige Funktionen bzw. Module des Spring Frameworks näher<br />

dargelegt. Diese können je nach Bedarf in das Framework eingebunden werden. Sie<br />

vereinfachen die Entwicklung von Java-Anwendungen und sind <strong>für</strong> den Entwickler eine<br />

gute Unterstützung. Die Funktionen bzw. Module, die in dieser Arbeit nicht vorgestellt<br />

wurden, sind in zahlreichen Büchern über das Spring Framework und auf Webseiten<br />

dokumentiert. Ausblickend lässt sich festhalten, dass aufgrund des hohen Interesses, das<br />

am Spring Framework <strong>der</strong>zeit besteht, davon ausgegangen werden kann, dass es auch<br />

zukünftig verwendet und weiterentwickelt wird.<br />

22


Anhang A: Klassendiagramm<br />

Anhang A: Klassendiagramm<br />

Abb. 1: Klassendiagramm Bibliothek<br />

23


Anhang B: Quellcode<br />

Anhang B: Quellcode<br />

LoggingAdvice.java<br />

package aop;<br />

import java.util.Arrays;<br />

import org.aopalliance.intercept.MethodInterceptor;<br />

import org.aopalliance.intercept.MethodInvocation;<br />

import org.apache.commons.logging.Log;<br />

import org.apache.commons.logging.LogFactory;<br />

/**<br />

* Logging Advice, den zu den zugeordneten Methoden<br />

Tracinginformationen<br />

* wie Methodenname, Parameter und Startzeit hinzufügt<br />

* @author Birgit<br />

*<br />

*/<br />

public class LoggingAdvice implements MethodInterceptor {<br />

private static long invocationID = 0;<br />

private static synchronized long getInvocationID() {<br />

return invocationID++;<br />

}<br />

/**<br />

* Methode, den zu den zugeordneten Methoden<br />

Tracinginformationen<br />

* wie Methodenname, Parameter und Startzeit hinzufügt<br />

* @param methodInvocation Methode, die erweitert wird<br />

*/<br />

public Object invoke(MethodInvocation methodInvocation)<br />

throws Throwable {<br />

Object result;<br />

}<br />

/**<br />

long startMillis;<br />

long endMillis;<br />

long id;<br />

Log log;<br />

log =<br />

LogFactory.getLog(getClassName(methodInvocation));<br />

id = getInvocationID();<br />

startMillis = System.currentTimeMillis();<br />

logMethodStart(log, methodInvocation, id,<br />

startMillis);<br />

try {<br />

result = methodInvocation.proceed();<br />

} catch (Throwable throwable) {<br />

endMillis = System.currentTimeMillis();<br />

logMethodException(log, methodInvocation, id,<br />

startMillis, endMillis, throwable);<br />

throw throwable;<br />

}<br />

endMillis = System.currentTimeMillis();<br />

logMethodEnd(log, methodInvocation, id, startMillis,<br />

endMillis, result);<br />

return result;<br />

24


Anhang B: Quellcode<br />

* ermittelt die Parameterwerte <strong>der</strong> aufgerufenen Methode<br />

* @param methodInvocation Methodenaufruf<br />

* @return gibt die Parameterwerte zurück<br />

*/<br />

private static String getArguments(MethodInvocation<br />

methodInvocation) {<br />

String result;<br />

Object[] args;<br />

args = methodInvocation.getArguments();<br />

if (args == null) {<br />

result = "[]";<br />

} else {<br />

result = Arrays.asList(args).toString();<br />

}<br />

return result;<br />

}<br />

/**<br />

* ermittelt den Methodennamen <strong>der</strong> aufgerufenen Methode<br />

* @param methodInvocation Methodenaufruf<br />

* @return Methodenname<br />

*/<br />

private static String getMethodName(MethodInvocation<br />

methodInvocation) {<br />

return methodInvocation.getMethod().getName();<br />

}<br />

/**<br />

* ermittelt den Klassenname <strong>der</strong> aufgerufenen Methode<br />

* @param methodInvocation Methodenaufruf<br />

* @return Klassename<br />

*/<br />

private static String getClassName(MethodInvocation<br />

methodInvocation) {<br />

String result;<br />

Object target;<br />

target = methodInvocation.getThis();<br />

if (target == null) {<br />

result = "null";<br />

} else {<br />

result = target.getClass().getName();<br />

}<br />

return result;<br />

}<br />

/**<br />

* gibt Logginginformation zur Exception des Methodenaufrufes<br />

aus<br />

* @param log Logger<br />

* @param methodInvocation Methodenaufruf<br />

* @param id Aufrufid<br />

* @param startMillis Startzeit <strong>der</strong> Methode<br />

* @param endMillis Endzeit <strong>der</strong> Methode<br />

* @param throwable Exception<br />

*/<br />

private void logMethodException(Log log,<br />

MethodInvocation methodInvocation,<br />

long id, long startMillis, long endMillis,<br />

Throwable throwable) {<br />

if (log.isInfoEnabled()) {<br />

StringBuffer sb = new StringBuffer();<br />

sb.append("MethodInvocation " + id<br />

+ " EXCEPTION");<br />

25


Anhang B: Quellcode<br />

}<br />

}<br />

sb.append("\n Class : " +<br />

getClassName(methodInvocation));<br />

sb.append("\n Method : " +<br />

getMethodName(methodInvocation));<br />

sb.append("\n Arguments : " +<br />

getArguments(methodInvocation));<br />

sb.append("\n Start:" + startMillis<br />

+ " ms");<br />

sb.append("\n End:" + endMillis + " ms");<br />

sb.append("\n Duration : " +<br />

(endMillis - startMillis) + " ms");<br />

sb.append("\n Result : " + throwable);<br />

log.info(sb);<br />

/**<br />

* gibt Logginginformation zum Start des Methodenaufrufes aus<br />

* @param log Logger<br />

* @param methodInvocation Methodenaufruf<br />

* @param id Aufrufid<br />

* @param startMillis Startzeit <strong>der</strong> Methode<br />

* @param endMillis Endzeit <strong>der</strong> Methode<br />

*/<br />

private void logMethodStart(Log log, MethodInvocation<br />

methodInvocation, long id, long startMillis) {<br />

if (log.isInfoEnabled()) {<br />

StringBuffer sb = new StringBuffer();<br />

sb.append("MethodInvocation " + id<br />

+ " START");<br />

sb.append("\n Class : " +<br />

getClassName(methodInvocation));<br />

sb.append("\n Method : " +<br />

getMethodName(methodInvocation));<br />

sb.append("\n Arguments : " +<br />

getArguments(methodInvocation));<br />

sb.append("\n Start : " + startMillis<br />

+ " ms");<br />

log.info(sb);<br />

}<br />

}<br />

/**<br />

* gibt Logginginformation zum Ende des Methodenaufrufes aus<br />

* @param log Logger<br />

* @param methodInvocation Methodenaufruf<br />

* @param id Aufrufid<br />

* @param startMillis Startzeit <strong>der</strong> Methode<br />

* @param endMillis Endzeit <strong>der</strong> Methode<br />

* @param result Ergebnis des Methodenaufrufs<br />

*/<br />

private static void logMethodEnd(Log log,<br />

MethodInvocation methodInvocation, long id,<br />

long startMillis, long endMillis, Object result) {<br />

if (log.isInfoEnabled()) {<br />

StringBuffer sb = new StringBuffer();<br />

sb.append("MethodInvocation " + id<br />

+ " END");<br />

sb.append("\n Class : " +<br />

getClassName(methodInvocation));<br />

sb.append("\n Method : " +<br />

26


Anhang B: Quellcode<br />

}<br />

Book.java<br />

}<br />

package bib;<br />

/**<br />

* Klasse Buch<br />

* @author Birgit<br />

*<br />

*/<br />

public class Book{<br />

/**<br />

* BuchID<br />

*/<br />

protected int id;<br />

/**<br />

* Beschreibung/Titel des Buchs<br />

*/<br />

protected String description;<br />

/**<br />

* ISBN des Buchs<br />

*/<br />

protected String isbn;<br />

/**<br />

* Author des Buchs<br />

*/<br />

protected String autor;<br />

}<br />

}<br />

getMethodName(methodInvocation));<br />

sb.append("\n Arguments : " +<br />

getArguments(methodInvocation));<br />

sb.append("\n Start : " + startMillis<br />

+ " ms");<br />

sb.append("\n End:" + endMillis + " ms");<br />

sb.append("\n Duration : " +<br />

(endMillis - startMillis) + " ms");<br />

sb.append("\n Result : " + result);<br />

log.info(sb);<br />

public Book(String description, String isbn, String autor) {<br />

this.description = description;<br />

this.isbn = isbn;<br />

this.autor = autor;<br />

}<br />

public int getId(){return id;}<br />

public void setId(int id){<br />

this.id = id;<br />

}<br />

public String getDescription(){return description;}<br />

public void setDescription(String description){<br />

this.description = description;<br />

}<br />

public String getISBN(){return isbn;}<br />

public void setISBN(String nr){isbn = nr;}<br />

public String getAutor(){return autor;}<br />

public void setAutor(String a){autor = a;}<br />

27


Anhang B: Quellcode<br />

Exemplar.java<br />

package bib;<br />

/**<br />

* Klasse Exemplar (Exemplar eines Buches)<br />

* @author Birgit<br />

*<br />

*/<br />

public class Exemplar {<br />

/**<br />

* ID des Exemplars<br />

*/<br />

protected int id;<br />

/**<br />

* Buch, das zu dem Exemplar gehört<br />

*/<br />

protected Book book;<br />

/**<br />

* mögliche Ausleihe des Exemplars<br />

*/<br />

protected Lending lending;<br />

public Exemplar(int id, Book book) {<br />

super();<br />

this.id = id;<br />

this.book = book;<br />

}<br />

public int getId()<br />

{<br />

return id;<br />

}<br />

public void setId(int id)<br />

{<br />

this.id = id;<br />

}<br />

public Book getBook()<br />

{<br />

return book;<br />

}<br />

public void setBook(Book b)<br />

{<br />

book = b;<br />

}<br />

public Lending getLending()<br />

{<br />

return lending;<br />

}<br />

public void setLending(Lending l)<br />

{<br />

lending = l;<br />

}<br />

}<br />

Lending.java<br />

28


Anhang B: Quellcode<br />

package bib;<br />

import java.util.Date;<br />

/**<br />

* Klasse Ausleihe<br />

* @author Birgit<br />

*<br />

*/<br />

public class Lending {<br />

/**<br />

* ID <strong>der</strong> Ausleihe<br />

*/<br />

protected int id;<br />

/**<br />

* Startdatum <strong>der</strong> Ausleihe<br />

*/<br />

protected Date date;<br />

/**<br />

* Benutzer, des das Exemplar ausgeliehen hat<br />

*/<br />

protected User user;<br />

/**<br />

* Exemplar, das ausgeliehen wurde<br />

*/<br />

protected Exemplar exemplar;<br />

{<br />

}<br />

User.java<br />

public Lending(int id, Date date, User user, Exemplar exemplar)<br />

super();<br />

this.id = id;<br />

this.date = date;<br />

this.user = user;<br />

this.exemplar = exemplar;<br />

}<br />

public int getId(){return id;}<br />

public void setId(int id){this.id = id;}<br />

public Date getDate(){return date;}<br />

public void setDate(Date d){date = d;}<br />

public User getUser(){return user;}<br />

public void setUser(User u){<br />

user = u;<br />

}<br />

public Exemplar getExemplar(){return exemplar;}<br />

public void setExemplar(Exemplar e){<br />

exemplar = e;<br />

}<br />

package bib;<br />

import java.util.ArrayList;<br />

import java.util.Collection;<br />

/**<br />

* Klasse Benutzer<br />

29


Anhang B: Quellcode<br />

* @author Birgit<br />

*<br />

*/<br />

public class User {<br />

/**<br />

* BenutzerID<br />

*/<br />

protected int id;<br />

/**<br />

* Anmeldename/User<br />

*/<br />

protected String username;<br />

/**<br />

* Vorname<br />

*/<br />

protected String firstname;<br />

/**<br />

* Nachname<br />

*/<br />

protected String lastname;<br />

/**<br />

* Password<br />

*/<br />

protected String password;<br />

protected Collection lending =<br />

new ArrayList();<br />

public User (String firstname,String lastname){<br />

}<br />

this.firstname = firstname;<br />

this.lastname = lastname;<br />

public int getId(){return id;}<br />

public void setId(int id){this.id = id;}<br />

public String getFirstname(){return firstname;}<br />

public void setFirstname(String firstname){<br />

this.firstname = firstname;<br />

}<br />

public String getLastname(){return lastname;}<br />

public void setLastname(String lastname){<br />

this.lastname = lastname;<br />

}<br />

public Collection getLending(){return lending;}<br />

public void setLending(Collection coll){<br />

lending = coll;<br />

}<br />

public String getPassword() {<br />

return password;<br />

}<br />

public void setPassword(String password) {<br />

this.password = password;<br />

}<br />

30


Anhang B: Quellcode<br />

}<br />

IBookDAO.java<br />

package dao;<br />

import java.util.List;<br />

public String getUsername() {<br />

return username;<br />

}<br />

public void setUsername(String username) {<br />

this.username = username;<br />

}<br />

import bib.Book;<br />

/**<br />

* Schnittstelle <strong>für</strong> DAO <strong>für</strong> Bücher<br />

* @author Birgit<br />

*<br />

*/<br />

public interface IBookDAO {<br />

}<br />

/**<br />

* gibt Liste aller Bücher zurück<br />

* @return Bücherliste<br />

*/<br />

List getAll();<br />

/**<br />

* gibt alle Bücher zur eingegeben Beschreibung zurück<br />

* @param description Beschreibung<br />

* @return Bücherliste<br />

*/<br />

List getByDescription(String description);<br />

/**<br />

* speichert das eingegebene Buch<br />

* @param book Buch<br />

* @return gespeicherte Buch<br />

*/<br />

Book save(Book book);<br />

/**<br />

* löscht alle Bücher zur eingegeben Beschreibung<br />

* @param description Beschreibung<br />

*/<br />

void deleteByDescription(String description);<br />

/**<br />

* gibt ein Buch zur eingegebenen ID zurück<br />

* @param id<br />

* @return Buch<br />

*/<br />

Book getByID(int id);<br />

/**<br />

* löscht das Bücher zur eingegeben ID<br />

* @param id<br />

*/<br />

void deleteByID(int id);<br />

/**<br />

* än<strong>der</strong>t das eingegebene Buch<br />

* @param book Buch<br />

*/<br />

void update(Book book);<br />

31


Anhang B: Quellcode<br />

IExemplarDAO.java<br />

package dao;<br />

import java.util.List;<br />

import bib.Exemplar;<br />

/**<br />

* Schnittstelle <strong>für</strong> DAO Exemplar<br />

* @author Birgit<br />

*<br />

*/<br />

public interface IExemplarDAO {<br />

/**<br />

* gibt Exemplare zur BuchID zurück<br />

* @param bookid BuchID<br />

* @return Exemplarliste<br />

*/<br />

List getByBook(String bookid);<br />

/**<br />

* speichert ein Exemplar<br />

* @param exemplar Exemplar<br />

* @return gespeichertes Exemplar<br />

*/<br />

Exemplar save(Exemplar exemplar);<br />

}<br />

ILendingDAO.java<br />

package dao;<br />

/**<br />

* gibt zur ID Exemplar zurück<br />

* @param id<br />

* @return Exemplar<br />

*/<br />

Exemplar getByID(int id);<br />

/**<br />

* löscht Exemplar zur ID<br />

* @param id<br />

*/<br />

void deleteByID(int id);<br />

/**<br />

* än<strong>der</strong>t ein Exemplar<br />

* @param exemplar Exemplar<br />

*/<br />

void update(Exemplar exemplar);<br />

import java.util.List;<br />

import bib.Lending;<br />

/**<br />

* Schnittstelle <strong>für</strong> DAO Ausleihe<br />

* @author Birgit<br />

*<br />

*/<br />

public interface ILendingDAO {<br />

/**<br />

* speichert eine Ausleihe<br />

* @param lending Ausleihe<br />

* @return gespeicherte Ausleihe<br />

32


Anhang B: Quellcode<br />

}<br />

*/<br />

public Lending save(Lending lending);<br />

/**<br />

* gibt Ausleihen zu einer Benutzerid zurück<br />

* @param userid Benutzerid<br />

* @return Ausleihenliste<br />

*/<br />

public List getByUserID(int userid);<br />

/**<br />

* gibt alle Ausleihen zurück<br />

* @return Ausleihenliste<br />

*/<br />

public List getAll();<br />

IUserDAO.java<br />

package dao;<br />

import java.util.List;<br />

import bib.User;<br />

/**<br />

* Schnittstelle DAO Benutzer<br />

* @author Birgit<br />

*<br />

*/<br />

public interface IUserDAO {<br />

/**<br />

* gibt den Benutzer zum Anmeldenamen zurück<br />

* @param username Anmeldename<br />

* @return Benutzer<br />

*/<br />

User getByName(String username);<br />

/**<br />

* speichert einen Benutzer<br />

* @param user Benutzer<br />

* @return gespeicherter Benutzer<br />

*/<br />

User save(User user);<br />

/**<br />

* löscht einen Benutzer zum Anmeldenamen<br />

* @param name Anmeldename<br />

*/<br />

void deleteByName(String name);<br />

/**<br />

* gibt einen Benutzer zur ID zurück<br />

* @param id<br />

* @return Benutzer<br />

*/<br />

User getByID(int id);<br />

/**<br />

* löscht eine Benutzer zur ID<br />

* @param id<br />

*/<br />

void deleteByID(int id);<br />

/**<br />

* gibt alle Benutzer zurück<br />

* @return Benutzerliste<br />

*/<br />

List getAll();<br />

}<br />

33


Anhang B: Quellcode<br />

bookDAO.java<br />

package jdbc;<br />

import java.sql.ResultSet;<br />

import java.sql.SQLException;<br />

import java.util.List;<br />

import javax.sql.DataSource;<br />

import org.springframework.dao.EmptyResultDataAccessException;<br />

import org.springframework.jdbc.core.RowMapper;<br />

import<br />

org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSourc<br />

e;<br />

import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;<br />

import<br />

org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;<br />

import bib.Book;<br />

import dao.IBookDAO;<br />

/**<br />

* DAO <strong>für</strong> Bücher<br />

* @author Birgit<br />

*<br />

*/<br />

public class BookDAO extends NamedParameterJdbcDaoSupport implements<br />

IBookDAO {<br />

/**<br />

* innere Klasse die eine RowMapper <strong>für</strong> Bücher zur Verfügung<br />

stellt<br />

*<br />

*/<br />

private static final class BookRowMapper implements RowMapper {<br />

/**<br />

* Methode zu Mappen von Bücher<br />

* @param rs Ergebnis <strong>der</strong> SQL-Abfrage<br />

* @param rowNum Anzahl Zeilen<br />

* @return Buchobjekt<br />

*/<br />

public Object mapRow(ResultSet rs, int rowNum) throws<br />

SQLException {<br />

Book Book = new<br />

Book(rs.getString(1),rs.getString(2),rs.getString(3));<br />

Book.setId(rs.getInt(4));<br />

return Book;<br />

}<br />

}<br />

public BookDAO(){<br />

}<br />

/**<br />

* Konstruktor<br />

* @param dataSource Datenquelle<br />

*/<br />

public BookDAO(DataSource dataSource) {<br />

setDataSource(dataSource);<br />

}<br />

/**<br />

* gibt alle Bücher zur eingegeben Beschreibung zurück<br />

* @param description Beschreibung<br />

* @return Bücherliste<br />

34


Anhang B: Quellcode<br />

*/<br />

public List getByDescription(String description) {<br />

MapSqlParameterSource params = new MapSqlParameterSource();<br />

params.addValue("description", description);<br />

return getNamedParameterJdbcTemplate()<br />

.query(<br />

"SELECT DESCRIPTION, ISBN, AUTOR, ID FROM Book<br />

WHERE DESCRIPTION=:description",<br />

params, new BookRowMapper());<br />

}<br />

/**<br />

* gibt ein Buch zur eingegebenen ID zurück<br />

* @param id<br />

* @return Buch<br />

*/<br />

public Book getByID(int id) {<br />

return (Book) getNamedParameterJdbcTemplate().<br />

queryForObject(<br />

"SELECT DESCRIPTION, ISBN, AUTOR, ID FROM Book<br />

WHERE ID=:id",<br />

new MapSqlParameterSource("id", id), new<br />

BookRowMapper());<br />

}<br />

/**<br />

* speichert das eingegebene Buch<br />

* @param book Buch<br />

* @return gespeicherte Buch<br />

*/<br />

public Book save(Book Book) {<br />

initTemplateConfig();<br />

getNamedParameterJdbcTemplate().update(<br />

"INSERT INTO Book (DESCRIPTION, ISBN, AUTOR)<br />

VALUES(:description, :isbn, :autor)",<br />

new BeanPropertySqlParameterSource(Book));<br />

return Book;<br />

}<br />

/**<br />

* löscht alle Bücher zur eingegeben Beschreibung<br />

* @param description Beschreibung<br />

*/<br />

public void deleteByDescription(String description) {<br />

getNamedParameterJdbcTemplate().update(<br />

"DELETE FROM Book WHERE DESCRIPTION=:description",<br />

new MapSqlParameterSource("description",<br />

description));<br />

}<br />

/**<br />

* löscht das Bücher zur eingegeben ID<br />

* @param id<br />

*/<br />

public void deleteByID(int id) {<br />

getNamedParameterJdbcTemplate().update("DELETE FROM Book WHERE<br />

ID=:id",<br />

new MapSqlParameterSource("id", id));<br />

}<br />

/**<br />

* än<strong>der</strong>t das eingegebene Buch<br />

* @param book Buch<br />

*/<br />

public void update(Book Book) {<br />

getNamedParameterJdbcTemplate()<br />

35


Anhang B: Quellcode<br />

}<br />

.update(<br />

"UPDATE Book SET<br />

DESCRIPTION=:description,ISBN=:isbn,AUTOR=:autor<br />

WHERE ID=:id",<br />

new BeanPropertySqlParameterSource(Book));<br />

}<br />

/**<br />

* gibt Liste aller Bücher zurück<br />

* @return Bücherliste<br />

*/<br />

public List getAll() {<br />

return (List) getJdbcTemplate().query(<br />

"SELECT DESCRIPTION, ISBN, AUTOR, ID FROM Book ",<br />

new BookRowMapper());<br />

}<br />

ExemplarDAO.java<br />

package jdbc;<br />

import java.sql.ResultSet;<br />

import java.sql.SQLException;<br />

import java.util.List;<br />

import javax.sql.DataSource;<br />

import org.springframework.jdbc.core.RowMapper;<br />

import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;<br />

import<br />

org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;<br />

import bib.Book;<br />

import bib.Exemplar;<br />

import dao.IBookDAO;<br />

/**<br />

* Klasse <strong>für</strong> DAO Exemplar<br />

* @author Birgit<br />

*<br />

*/<br />

public class ExemplarDAO extends NamedParameterJdbcDaoSupport<br />

implements dao.IExemplarDAO{<br />

/**<br />

* BuchDAO<br />

*/<br />

private static IBookDAO bookDAO;<br />

/**<br />

*<br />

* innere Klasse, die einen RowMapper <strong>für</strong> Exemplar zur Verfügung<br />

stellt<br />

*<br />

*/<br />

private static final class ExemplarRowMapper implements<br />

RowMapper {<br />

/**<br />

* Methode zu mappen einer SQL Abfrage auf Exemplar-Objekte<br />

* @param rs Ergebnis <strong>der</strong> SQL-Abfrage<br />

* @param rowNum Anzahl Zeilen<br />

* @return Exemplarobjekt<br />

*/<br />

public Object mapRow(ResultSet rs, int rowNum) throws<br />

36


Anhang B: Quellcode<br />

}<br />

}<br />

SQLException {<br />

Book book = bookDAO.getByID(rs.getInt(2));<br />

Exemplar exemplar = new Exemplar(rs.getInt(1),book);<br />

return exemplar;<br />

public ExemplarDAO() {<br />

}<br />

/**<br />

* Konstruktor<br />

* @param dataSource Datenquelle<br />

*/<br />

public ExemplarDAO(DataSource dataSource) {<br />

setDataSource(dataSource);<br />

}<br />

/**<br />

* gibt Exemplare zur BuchID zurück<br />

* @param bookid BuchID<br />

* @return Exemplarliste<br />

*/<br />

public List getByBook(String bookid){<br />

MapSqlParameterSource params = new<br />

MapSqlParameterSource();<br />

params.addValue("bookid", bookid);<br />

return getNamedParameterJdbcTemplate()<br />

.query( "SELECT ID, BOOKID FROM Exemplar WHERE<br />

BOOKID=:bookid",<br />

params, new ExemplarRowMapper());<br />

}<br />

/**<br />

* speichert ein Exemplar<br />

* @param exemplar Exemplar<br />

* @return gespeichertes Exemplar<br />

*/<br />

public Exemplar save(Exemplar exemplar){<br />

initTemplateConfig();<br />

getJdbcTemplate()<br />

.update(<br />

"INSERT INTO Exemplar (ID, BOOKID)<br />

VALUES(?, ?)",<br />

new Object[] {exemplar.getId(),<br />

exemplar.getBook().getId()});<br />

return exemplar;<br />

}<br />

/**<br />

* gibt zur ID Exemplar zurück<br />

* @param id<br />

* @return Exemplar<br />

*/<br />

public Exemplar getByID(int id){<br />

return (Exemplar) getNamedParameterJdbcTemplate().<br />

queryForObject(<br />

"SELECT ID, BOOKID FROM Exemplar WHERE ID=:id",<br />

new MapSqlParameterSource("id", id), new<br />

ExemplarRowMapper());<br />

}<br />

/**<br />

* löscht Exemplar zur ID<br />

* @param id<br />

37


Anhang B: Quellcode<br />

}<br />

*/<br />

public void deleteByID(int id){<br />

getNamedParameterJdbcTemplate().update("DELETE FROM<br />

Exemplar WHERE ID=:id",<br />

new MapSqlParameterSource("id", id));<br />

}<br />

/**<br />

* än<strong>der</strong>t ein Exemplar<br />

* @param exemplar Exemplar<br />

*/<br />

public void update(Exemplar exemplar){<br />

getJdbcTemplate()<br />

.update(<br />

"UPDATE Exemplar SET ID=?,BOOKID=? WHERE ID=?",<br />

new Object[] {exemplar.getId(),<br />

exemplar.getBook().getId()});<br />

}<br />

public IBookDAO getBookDAO() {<br />

return bookDAO;<br />

}<br />

public void setBookDAO(IBookDAO bookDAO) {<br />

this.bookDAO = bookDAO;<br />

}<br />

LendingDAO.java<br />

package jdbc;<br />

import java.sql.ResultSet;<br />

import java.sql.SQLException;<br />

import java.util.List;<br />

import javax.sql.DataSource;<br />

import org.springframework.jdbc.core.RowMapper;<br />

import org.springframework.jdbc.core.SqlParameter;<br />

import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;<br />

import<br />

org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;<br />

import bib.User;<br />

import bib.Exemplar;<br />

import bib.Lending;<br />

import dao.IExemplarDAO;<br />

import dao.IUserDAO;<br />

/**<br />

* Klasse <strong>für</strong> DAO Ausleihe<br />

* @author Birgit<br />

*<br />

*/<br />

public class LendingDAO extends NamedParameterJdbcDaoSupport<br />

implements dao.ILendingDAO {<br />

/**<br />

* Exemplar DAO<br />

38


Anhang B: Quellcode<br />

{<br />

}<br />

*/<br />

private static IExemplarDAO exemplarDAO;<br />

/**<br />

* Benutzer DAO;<br />

*/<br />

private static IUserDAO userDAO;<br />

/**<br />

* innere Klasse, die RowMapper <strong>für</strong> Ausleihen zur Verfügung stellt<br />

*<br />

*/<br />

private static final class LendingRowMapper implements RowMapper<br />

}<br />

/**<br />

* Methode zum Mappen von SQL-Ergebnis auf AusleihObjekte<br />

* @param rs Ergebnis <strong>der</strong> SQL-Abfrage<br />

* @param rowNum Anzahl Zeilen<br />

* @return Ausleihobjekt<br />

*/<br />

public Object mapRow(ResultSet rs, int rowNum) throws<br />

SQLException {<br />

User user = userDAO.getByID(rs.getInt(3));<br />

Exemplar exemplar = exemplarDAO.getByID(rs.getInt(4));<br />

Lending lending = new Lending(rs.getInt(1),rs.getDate(2),<br />

user, exemplar);<br />

return lending;<br />

}<br />

public LendingDAO() {<br />

super();<br />

public LendingDAO(DataSource dataSource, IExemplarDAO<br />

exemplarDAO, IUserDAO userDAO) {<br />

setDataSource(dataSource);<br />

this.exemplarDAO = exemplarDAO;<br />

this.userDAO = userDAO;<br />

}<br />

/**<br />

* speichert eine Ausleihe<br />

* @param lending Ausleihe<br />

* @return gespeicherte Ausleihe<br />

*/<br />

public Lending save(Lending lending) {<br />

initTemplateConfig();<br />

getJdbcTemplate()<br />

.update(<br />

"INSERT INTO Lending (ID, DATE, USERID,<br />

EXEMPLARID) VALUES(?, ?, ?, ?)",<br />

new Object[] {lending.getId(),<br />

lending.getDate(), lending.getUser().getId(),<br />

lending.getExemplar().getId()});<br />

return lending;<br />

}<br />

/**<br />

* gibt Ausleihen zu einer Benutzerid zurück<br />

39


Anhang B: Quellcode<br />

}<br />

UserDAO.java<br />

package jdbc;<br />

* @param userid Benutzerid<br />

* @return Ausleihenliste<br />

*/<br />

public List getByUserID(int userid) {<br />

MapSqlParameterSource params = new<br />

MapSqlParameterSource();<br />

params.addValue("userid", userid);<br />

return getNamedParameterJdbcTemplate()<br />

.query(<br />

"SELECT ID, DATE, USERID, EXEMPLARID<br />

FROM Lending WHERE USERID=:userid",<br />

params, new LendingRowMapper());<br />

}<br />

/**<br />

* gibt alle Ausleihen zurück<br />

* @return Ausleihenliste<br />

*/<br />

public List getAll() {<br />

MapSqlParameterSource params = new<br />

MapSqlParameterSource();<br />

return getNamedParameterJdbcTemplate()<br />

.query(<br />

"SELECT ID, DATE, USERID, EXEMPLARID<br />

FROM Lending",<br />

params, new LendingRowMapper());<br />

}<br />

public IExemplarDAO getExemplarDAO() {<br />

return exemplarDAO;<br />

}<br />

public void setExemplarDAO(IExemplarDAO exemplarDAO) {<br />

this.exemplarDAO = exemplarDAO;<br />

}<br />

public IUserDAO getUserDAO() {<br />

return userDAO;<br />

}<br />

public void setUserDAO(IUserDAO userDAO) {<br />

this.userDAO = userDAO;<br />

}<br />

import java.sql.ResultSet;<br />

import java.sql.SQLException;<br />

import java.util.HashMap;<br />

import java.util.List;<br />

import java.util.Map;<br />

import javax.sql.DataSource;<br />

import org.springframework.jdbc.core.RowMapper;<br />

import<br />

org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;<br />

40


Anhang B: Quellcode<br />

import bib.User;<br />

import dao.IUserDAO;<br />

/**<br />

* Klasse <strong>für</strong> DAO Benutzer<br />

* @author Birgit<br />

*<br />

*/<br />

public class UserDAO extends NamedParameterJdbcDaoSupport implements<br />

IUserDAO{<br />

/**<br />

* innere Klasse, die RowMapper <strong>für</strong> Benutzer zur Verfügung stellt<br />

*<br />

*/<br />

private static final class UserResultSetRowMapper implements<br />

RowMapper {<br />

/**<br />

* Methode zum Mappen von SQL-Ergebnis auf BenutzerObjekte<br />

* @param rs Ergebnis <strong>der</strong> SQL-Abfrage<br />

* @param rowNum Anzahl Zeilen<br />

* @return Benutzerobjekt<br />

*/<br />

public Object mapRow(ResultSet rs, int rowNum) throws<br />

SQLException {<br />

User user = new User( rs.getString(3),rs.getString(4));<br />

user.setId(rs.getInt(1));<br />

user.setUsername(rs.getString(2));<br />

return user;<br />

}<br />

}<br />

}<br />

public UserDAO() {<br />

super();<br />

public UserDAO(DataSource dataSource) {<br />

setDataSource(dataSource);<br />

}<br />

/**<br />

* löscht eine Benutzer zur ID<br />

* @param id<br />

*/<br />

public void deleteByID(int id) {<br />

Map parameters = new HashMap();<br />

parameters.put("id", id);<br />

getNamedParameterJdbcTemplate().update<br />

("DELETE FROM USER WHERE ID=?",<br />

parameters);<br />

}<br />

/**<br />

* gibt einen Benutzer zur ID zurück<br />

* @param id<br />

* @return Benutzer<br />

*/<br />

public User getByID(int id) {<br />

Map parameters = new HashMap();<br />

parameters.put("ID", id);<br />

return (User) getNamedParameterJdbcTemplate().queryForObject(<br />

"SELECT * FROM USER WHERE ID = (:ID)" ,<br />

parameters<br />

41


Anhang B: Quellcode<br />

}<br />

, new UserResultSetRowMapper());<br />

}<br />

/**<br />

* gibt den Benutzer zum Anmeldenamen zurück<br />

* @param username Anmeldename<br />

* @return Benutzer<br />

*/<br />

public User getByName(String username) {<br />

Map parameters = new HashMap();<br />

parameters.put("USERNAME", username);<br />

return (User) getNamedParameterJdbcTemplate()<br />

.queryForObject(<br />

"SELECT * FROM USER WHERE USERNAME=<br />

(:USERNAME)",<br />

parameters, new UserResultSetRowMapper());<br />

}<br />

/**<br />

* löscht einen Benutzer zum Anmeldenamen<br />

* @param name Anmeldename<br />

*/<br />

public void deleteByName(String name) {<br />

getJdbcTemplate().update("DELETE FROM USER WHERE USERNAME=?",<br />

new Object[] { name });<br />

}<br />

/**<br />

* speichert einen Benutzer<br />

* @param user Benutzer<br />

* @return gespeicherter Benutzer<br />

*/<br />

public User save(User user) {<br />

Map parameters = new HashMap();<br />

parameters.put("firstname", user.getFirstname());<br />

parameters.put("lastname", user.getLastname());<br />

parameters.put("username", user.getUsername());<br />

parameters.put("password", user.getPassword());<br />

getNamedParameterJdbcTemplate().update(<br />

"INSERT INTO<br />

USER(FIRSTNAME,LASTNAME,USERNAME,PASSWORD) " +<br />

"VALUES(:firstname,:lastname,:username,:password)",<br />

parameters);<br />

return user;<br />

}<br />

/**<br />

* gibt alle Benutzer zurück<br />

* @return Benutzerliste<br />

*/<br />

public List getAll() {<br />

List result = (List) getJdbcTemplate().query(<br />

"SELECT * FROM USER",<br />

new Object[] {}, new UserResultSetRowMapper());<br />

return result;<br />

}<br />

42


Anhang B: Quellcode<br />

BookController.java<br />

package mvc;<br />

import services.BookService;<br />

import java.util.HashMap;<br />

import java.util.Map;<br />

import javax.servlet.http.HttpServletRequest;<br />

import javax.servlet.http.HttpServletResponse;<br />

import org.springframework.web.servlet.ModelAndView;<br />

import org.springframework.web.servlet.mvc.AbstractController;<br />

/**<br />

* Controller, <strong>der</strong> das Modell und die View zu einer Bücheranfrage<br />

zurückgibt<br />

* @author Birgit<br />

*<br />

*/<br />

public class BookController extends AbstractController{<br />

/**<br />

* Verweis auf Bücherservice<br />

*/<br />

private BookService bookService;<br />

/**<br />

* Viewname<br />

*/<br />

private String view = "booklist";<br />

}<br />

public BookService getBookService() {<br />

return bookService;<br />

}<br />

public void setBookService(BookService bookService) {<br />

this.bookService = bookService;<br />

}<br />

/**<br />

* gibt das Modell und die View zu einer Bücheranfrage<br />

zurückgibt<br />

* @param request HttpRequest<br />

* @param response HTTP Response<br />

*/<br />

protected ModelAndView handleRequestInternal(HttpServletRequest<br />

request, HttpServletResponse response) throws Exception {<br />

}<br />

LendingController.java<br />

package mvc;<br />

Map model = new HashMap();<br />

model.put("books", bookService.getBooks());<br />

return new ModelAndView(view,model);<br />

import java.util.HashMap;<br />

import java.util.Map;<br />

43


Anhang B: Quellcode<br />

import javax.servlet.http.HttpServletRequest;<br />

import javax.servlet.http.HttpServletResponse;<br />

import org.springframework.security.context.SecurityContextHol<strong>der</strong>;<br />

import org.springframework.web.servlet.ModelAndView;<br />

import org.springframework.web.servlet.mvc.AbstractController;<br />

import services.LendingService;<br />

/**<br />

* Controller, <strong>der</strong> das Modell und die View zu einer Ausleihanfrage<br />

zurückgibt<br />

* @author Birgit<br />

*<br />

*/<br />

public class LendingController extends AbstractController{<br />

/**<br />

* Viewname<br />

*/<br />

private String view = "lendinglist";<br />

/**<br />

* Service Ausleihe<br />

*/<br />

private LendingService lendingService;<br />

/**<br />

* gibt das Modell und die View zu einer Anfrage zurückgibt<br />

* @param request HttpRequest<br />

* @param response HTTP Response<br />

*/<br />

protected ModelAndView<br />

handleRequestInternal(HttpServletRequest request,<br />

HttpServletResponse response) throws Exception {<br />

}<br />

String user = (String)<br />

SecurityContextHol<strong>der</strong>.getContext().<br />

getAuthentication().getName();<br />

Map model = new HashMap();<br />

model.put("lendings",<br />

lendingService.getLendings(user));<br />

return new ModelAndView(view,model);<br />

}<br />

public LendingService getLendingService() {<br />

return lendingService;<br />

}<br />

public void setLendingService(LendingService lendingService) {<br />

this.lendingService = lendingService;<br />

}<br />

LoginController.java<br />

package mvc;<br />

import java.util.HashMap;<br />

import java.util.Map;<br />

import javax.servlet.http.HttpServletRequest;<br />

import javax.servlet.http.HttpServletResponse;<br />

44


Anhang B: Quellcode<br />

import org.springframework.web.servlet.ModelAndView;<br />

import org.springframework.web.servlet.mvc.AbstractController;<br />

/**<br />

* Controller, <strong>der</strong> das Modell und die View zu einer LoginAnfrage<br />

zurückgibt<br />

* @author Birgit<br />

*<br />

*/<br />

public class LoginController extends AbstractController{<br />

/**<br />

* gibt die View zu einer LoginAnfrage zurückgibt<br />

* @param request HttpRequest<br />

* @param response HTTP Response<br />

*/<br />

protected ModelAndView handleRequestInternal(HttpServletRequest<br />

request,HttpServletResponse response) throws Exception {<br />

return new ModelAndView("login");<br />

}<br />

}<br />

StartController.java<br />

package mvc;<br />

import java.util.HashMap;<br />

import java.util.Map;<br />

import javax.servlet.http.HttpServletRequest;<br />

import javax.servlet.http.HttpServletResponse;<br />

import org.springframework.security.Authentication;<br />

import org.springframework.security.context.SecurityContextHol<strong>der</strong>;<br />

import org.springframework.web.servlet.ModelAndView;<br />

import org.springframework.web.servlet.mvc.AbstractController;<br />

import services.UserService;<br />

/**<br />

* Controller, <strong>der</strong> das Modell und die View zu einer Anfrage zurückgibt<br />

* @author Birgit<br />

*<br />

*/<br />

public class StartController extends AbstractController{<br />

/**<br />

* gibt das Modell und die View zu einer Anfrage zurückgibt<br />

* @param request HttpRequest<br />

* @param response HTTP Response<br />

*/<br />

protected ModelAndView handleRequestInternal(HttpServletRequest<br />

request, HttpServletResponse response) throws Exception {<br />

Authentication auth =<br />

SecurityContextHol<strong>der</strong>.getContext().getAuthentication();<br />

if(SecurityContextHol<strong>der</strong>.getContext()<br />

.getAuthentication().getName().toString().<br />

equals("anonymousUser")<br />

|| ! (auth.isAuthenticated()))<br />

return new ModelAndView("login");<br />

for (int i= 0; i


Anhang B: Quellcode<br />

}<br />

}<br />

Usercontroller.java<br />

package mvc;<br />

import java.util.HashMap;<br />

import java.util.Map;<br />

return new ModelAndView("admin/user");<br />

}<br />

}<br />

return new ModelAndView("start");<br />

import javax.servlet.http.HttpServletRequest;<br />

import javax.servlet.http.HttpServletResponse;<br />

import org.springframework.web.servlet.ModelAndView;<br />

import org.springframework.web.servlet.mvc.AbstractController;<br />

import services.UserService;<br />

/**<br />

* Controller gibt das Modell und die View zu einer Anfrage<br />

zurückgibt<br />

* @author Birgit<br />

*<br />

*/<br />

public class UserController extends AbstractController{<br />

/**<br />

* Viewname<br />

*/<br />

private String view = "admin/userlist";<br />

/**<br />

* Service User<br />

*/<br />

private UserService userService;<br />

/**<br />

* gibt das Modell und die View zu einer Anfrage zurückgibt<br />

* @param request HttpRequest<br />

* @param response HTTP Response<br />

*/<br />

protected ModelAndView<br />

handleRequestInternal(HttpServletRequest request,<br />

HttpServletResponse response) throws Exception {<br />

Map model = new HashMap();<br />

model.put("users", userService.getUsers());<br />

return new ModelAndView(view,model);<br />

}<br />

}<br />

public UserService getUserService() {<br />

return userService;<br />

}<br />

public void setUserService(UserService userService) {<br />

this.userService = userService;<br />

}<br />

BookService.java<br />

package services;<br />

46


Anhang B: Quellcode<br />

import java.util.List;<br />

import dao.IBookDAO;<br />

/**<br />

* Serivceschicht Book<br />

* @author Birgit<br />

*<br />

*/<br />

public class BookService {<br />

/**<br />

* DAO Book<br />

*/<br />

private IBookDAO bookDAO;<br />

/**<br />

* gibt alle Bücher zurück<br />

* @return Bücherliste<br />

*/<br />

public List getBooks(){<br />

return bookDAO.getAll();<br />

}<br />

public IBookDAO getBookDAO() {<br />

return bookDAO;<br />

}<br />

public void setBookDAO(IBookDAO bookDAO) {<br />

this.bookDAO = bookDAO;<br />

}<br />

}<br />

LendingService.java<br />

package services;<br />

import java.util.List;<br />

import dao.ILendingDAO;<br />

import dao.IUserDAO;<br />

import bib.Lending;<br />

import bib.User;<br />

/**<br />

* Serviceschicht Lending<br />

* @author Birgit<br />

*<br />

*/<br />

public class LendingService {<br />

/**<br />

* DAO Lending<br />

*/<br />

private ILendingDAO lendingDAO;<br />

/**<br />

* DAO User<br />

*/<br />

private IUserDAO userDAO;<br />

/**<br />

* gibt alle Ausleihen eines Benutzers zurück<br />

* @param username Benutzername<br />

* @return Ausleihliste<br />

*/<br />

public List getLendings(String username){<br />

User user = (User) userDAO.getByName(username);<br />

47


Anhang B: Quellcode<br />

}<br />

}<br />

int userid = user.getId();<br />

return lendingDAO.getByUserID(userid);<br />

public ILendingDAO getLendingDAO() {<br />

return lendingDAO;<br />

}<br />

public void setLendingDAO(ILendingDAO lendingDAO) {<br />

this.lendingDAO = lendingDAO;<br />

}<br />

public IUserDAO getUserDAO() {<br />

return userDAO;<br />

}<br />

public void setUserDAO(IUserDAO userDAO) {<br />

this.userDAO = userDAO;<br />

}<br />

UserService.java<br />

package services;<br />

import java.util.List;<br />

import bib.User;<br />

import dao.IUserDAO;<br />

/**<br />

* Serviceschicht User<br />

* @author Birgit<br />

*<br />

*/<br />

public class UserService {<br />

/**<br />

* User DAO<br />

*/<br />

private IUserDAO userDAO;<br />

/**<br />

* gibt alle Benutzer zurück<br />

* @return Benutzerliste<br />

*/<br />

public List getUsers(){<br />

return userDAO.getAll();<br />

}<br />

/**<br />

* legt einen Benutzer in <strong>der</strong> DB an<br />

* @param user Benutzer<br />

*/<br />

public void createUser(User user) {<br />

userDAO.save(user);<br />

}<br />

public IUserDAO getUserDAO() {<br />

return userDAO;<br />

}<br />

public void setUserDAO(IUserDAO userDAO) {<br />

this.userDAO = userDAO;<br />

48


Anhang B: Quellcode<br />

}<br />

}<br />

applicationContext.xml<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

49


Anhang B: Quellcode<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

SELECT USERNAME, PASSWORD, ENABLE as enabled<br />

FROM USER<br />

WHERE USERNAME = ?<br />

<br />

<br />

50


Anhang B: Quellcode<br />

<br />

<br />

SELECT u.USERNAME , a.AUTORITY as authority<br />

FROM AUTORITY a , USER u<br />

WHERE a.USERNAME = u.USERNAME<br />

AND u.USERNAME = ?<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

CONVERT_TO_LOWERCASE_BEFORE_COMPARISON<br />

PATTERN_TYPE_APACHE_ANT<br />

/book.htm=ROLE_USER<br />

/lending.htm=ROLE_USER<br />

/admin/user.htm=ROLE_ADMIN<br />

<br />

51


Anhang B: Quellcode<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON<br />

PATTERN_TYPE_APACHE_ANT<br />

/**=httpSessionContextIntegrationFilter,logoutFilter,<br />

authenticationProcessingFilter,exceptionTranslationFilter,<br />

filterSecurityInterceptor<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />


Anhang B: Quellcode<br />

logout.SecurityContextLogoutHandler"/><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

services.BookService.getBooks=ROLE_USER<br />

services.LendingService.getLendings=ROLE_USER<br />

services.UserService.getUsers=ROLE_ADMIN<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

securityInterceptor<br />

loggingInterceptor<br />

<br />

<br />

<br />

<br />

bookService<br />

lendingService<br />

userService<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

53


Anhang B: Quellcode<br />

springapp-servlet.xml<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

web.xml<br />

<br />

<br />

<br />

<br />

org.springframework.web.context.<br />

54


Anhang B: Quellcode<br />

ContextLoa<strong>der</strong>Listener<br />

<br />

<br />

<br />

filterChainProxy<br />

org.springframework.security.util.<br />

FilterToBeanProxy<br />

<br />

targetClass<br />

org.springframework.security.<br />

util.FilterChainProxy<br />

<br />

<br />

<br />

filterChainProxy<br />

/*<br />

<br />

SpringApp<br />

<br />

index.html<br />

index.htm<br />

index.jsp<br />

<br />

<br />

springapp<br />

org.springframework.web.servlet.<br />

DispatcherServlet<br />

1<br />

<br />

<br />

springapp<br />

*.htm<br />

<br />

<br />

index.jsp<br />

<br />

<br />

<br />

start.jsp<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Bibliothek<br />

<br />

55


Anhang B: Quellcode<br />

<br />

<br />

Willkommen <br />

auf <strong>der</strong> Webseite <strong>der</strong> Bibliothek!<br />

<br />

Was möchten Sie tun?<br />

Bücherliste einsehen<br />

aktuelle Ausleihen<br />

Logout<br />

<br />

<br />

<br />

login.jsp<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Bibliothek: Anmeldung<br />

<br />

<br />

<br />

Willkommen <strong>der</strong> Webseite <strong>der</strong> Bibliothek!<br />

<br />

Sie müssen sich anmelden bevor Sie unseren Service<br />

in Anspruch nehmen können.<br />

<br />

Benutzer: <br />

Password: <br />

<br />

<br />

<br />

<br />

<br />

lending.jsp<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Ausleihen<br />

<br />

56


Anhang B: Quellcode<br />

<br />

Willkommen: <br />

Hier sehen Sie alle von Ihnen ausgeliehenen Bücher<br />

<br />

<br />

DatumBenutzerExemplar<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

booklist.jsp<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Bücherliste<br />

<br />

<br />

<br />

Willkommen: <br />

Hier sehen Sie alle verfügbaren Bücher<br />

<br />

<br />

BuchAutor<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

user.jsp<br />

<br />

<br />

57


Anhang B: Quellcode<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Bibliothek: Userverwaltung<br />

<br />

<br />

<br />

Willkommen: <br />

Was möchten Sie tun?<br />

Benutzerliste einsehen<br />

Logout<br />

<br />

<br />

<br />

userlist.jsp<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Bibliothek: Benutzer<br />

<br />

<br />

<br />

Willkommen: <br />

Hier sehen Sie eine Liste aller Benutzer<br />

<br />

<br />

IDUsernameVorname<br />

Nachname<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

58


Anhang B: Quellcode<br />

<br />

<br />

<br />

<br />

59


Literaturverzeichnis<br />

[FaSc97] Fayad, Mohamed E.; Schmidt, Douglas C.: Object-Oriented Application<br />

Frameworks. ACM, 40, S. 32-38, ACM, 1997.<br />

[Fo04] Fowler, Martin: Inversion of Control Containers and the Dependency<br />

Injection Pattern. http://martinfowler.com/articles/injection.html.<br />

Abrufdatum: 28.09.2008.<br />

[GHJV04] Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John:<br />

Entwurfsmuster - Elemente wie<strong>der</strong>verwendbarer objektorientierter<br />

Software. Addison Wesley Verlag, 2004.<br />

[Wa08] Walls, Craig: Spring im Einsatz. Hanser Verlag, 2008.<br />

[Wo07] Wolff, Eberhard: Spring 2. dpunkt, 2007.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!