Forschungszentrum
Informatik
Universität
Karlsruhe (TH)
Information Process Engineering
Web-Technologien im praktischen Einsatz
Erstellung einer Bildsuchmaschine
mit Apache Wicket
Andreas Walter
WS 2009/2010
SVN Tutorial
Tutorial Folien und Sourcen zum Download
http://www.awalter.info/wicket/
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
2
Motivation: EU Projekt IMAGINATION
Anforderungen
Anwendung soll in JAVA entwickelt werden
Anwendung soll vollständig webbasiert sein und AJAX
verwenden, um desktop-charakter zu erzeugen
Anwendung muss verteilt entwickelt werden, erfordert
Versionskontrolle (auch von verwendeten Bibliotheken)
Integrationskontrolle von Teilentwicklungen
Webrahmenwerk, da Wechsel der Entwickler möglich
muss leicht erlernbar sein
Quelltext muss leicht lesbar sein
Einfache Änderung des Seitenlayouts
Anwendung durchläuft mehrere Zyklen (vom Prototyp an)
Seitenlayout durch Partner für Design
Informationsintegration & Web-Portale
WS 2009/10
3
Gliederung
Web-Technologien im praktischen Einsatz
Infrastruktur aufbauen
Framework wählen
Wicket Tutorial
Erstellung einer Bildsuchmaschine mit Wicket
Features von Wicket
Wicket im Vergleich zu anderen Frameworks
Wicket Schritt für Schritt zur Erstellung einer
Bildsuchmaschine
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
4
Infrastruktur aufbauen
JUnit: automatisches Testen der Programmfunktionen
Maven: Build Kontrolle
„continous integration server“
JUnit
JUNIT: http://www.junit.org/
Zweck:
Ermöglicht die Definition von Testfällen, um die Richtigkeit von
Quelltexten zu überprüfen
Beispiel
Methode public int getResult() muss „1“ zurückgeben
Test in Junit:
assertEquals(getResult(),1)
Falls int !=1 bricht der Test mit Fehlermeldung ab
JUnit ermöglicht die Integrationskontrolle von Anwendungsteilen
In IMAGINATION:
Test von verteilt entwickelten Anwendungsteilen
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
6
Maven: Build Kontrolle (1)
Maven Homepage: http://maven.apache.org/
Maven ermöglicht
Definition von Modulen einer umfangreichen Anwendung
Definition der Abhängigkeiten, z.B. JAR Files (Lucene, MySQL JDBC
Treiber) und der für Anwendung benötigten Versionsnummern
Automatische Durchführung von Kompilierung, JUnit-Tests,
Deployment
Direktes Starten von Webanwendungen in Servlet-Container
Integration der Anwendung in Eclipse
Ermöglicht einheiltliche Programmstrukturen
Src/main/java: Verzeichnis für JAVA Packages
Src/test/java: Verzeichnis für JUnit Tests
Target/classes: Verzeichnis für JAVA classes
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
7
Maven: Build Kontrolle (2)
Wichtige Build Targets von maven (jeweils
darüberliegende targets werden automatisch
durchgeführt)
mvn
mvn
mvn
mvn
compile: Kompiliert die Anwendung
test: Durchführung der JUnit Tests
install: Generierung von JAR Files
deploy: Aufladen der JAR Files auf einen Server
mvn jetty:run : Starten von Jetty Servlet Container
mvn eclipse:eclipse: Erstellung von Eclipse Projekts
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
8
continous integration server(1)
Zweck
Sorgen für automatische Erstellung von builds einer verteilt
erstellten Anwendung
Ablauf
Quellcodes werden in SVN Repository eingestellt
Projekte basieren auf Maven
Projekte enthalten JUnit Tests
Continous integration server prüft regelmässig SVN Repository auf
Änderungen
Bei Änderungen wird automatisch ein Build durchgeführt
Benachrichtigung der Entwickler bei Fehlern
Ermöglicht in Zusammenarbeit mit maven die automatische
Integrationskontrolle von Teilentwicklungen und die
Versionierung der Software
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
9
continous integration server(2)
Beispiel: Hudson - https://hudson.dev.java.net/
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
10
Auswahl des richtigen Frameworks
Wartbarkeit
Lesbarkeit
Model View Controler vs. Eventbasierten Frameworks
Langfristige Wartbarkeit
„Trennung von Anwendung und Darstellung“ ist nicht so
wichtig?
„Trennung von Anwendung und Darstellung kann jedes
Web Framework?“
Sicher?
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
12
Wartbarkeit in JSP 1.0
<html>
<head>
<title>A JSP example</title>
</head>
<body>
<%
%>
<%
%>
String[] valueArray = {"This", "is", "a", „string", „array", "example"};
int i;
for (i = 0; i < valueArray.length; i++)
{
<%= valueArray[i] %>
}
</body>
</html>
<%> <%> ??
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
13
Wartbarkeit in JSP 1.1, 1.2
etwas schöner mit JSF Tags
<BODY>
<f:view>
<h:dataTable value=„#{articleListBean.articles}“>
<h:column>
<h:outputText value=„Article“/>
<h:column>
<h:column>
<ho:outputText value=„article.name“/>
</h:column>
</h:dataTable>
<f:view>
</BODY>
Kann das die Designabteilung auch?
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
14
Ideale Wartbarkeit
Pures HTML – ein Framework muss das unterstützen
<html >
<head>
<title>Login Form mit Facelets<title>
</head>
<body>
Login:
<form id='myForm' jsfc='h:form'>
<input type='text' id='myInput' jsfc='h:inputText' value='# {SimpleBean.name}' />
<input type='submit' value='Abschicken' id='myBtn' jsfc='h:commandButton' />
</form>
</body>
</html>
Das kann die Designabteilung
Rahmenwerk: JSF mit Erweiterung Facelets
Und der Entwickler muss nur Marken einfügen, hier ‚jsfc‘ als Referenz zu JSF-Komponenten
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
15
Einfache Änderungen des Seitenlayouts
Möglich, wenn
HTML und Anwendungscode strikt getrennt sind
Was viele Rahmenwerke versprechen, aber nicht immer halten
Aus Praxis: ideal ist, ein Rahmenwerk erzwingt die Trennung,
sonst wird die Trennung (meist aus zeitgründen,
Bequemlichkeit, …) nicht eingehalten
Ein Rahmenwerk die Formatierung von Komponenten mit
CSS ermöglicht
Trennung ist wichtig
Nicht jedes Framework erfüllt diese Anforderung
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
16
Lesbarkeit (1)
Was macht dieses nette kleine Skript:
$result = "$1\n"
while m { < \s* A \s+ HREF \s* = \s* "([[^"\ ]*)" \s* > }
gsix;
In Perl zur Extraktion von Links in HTML Texten
<A HREF=„http://www.fzi.de“>
=> http://www.fzi.de
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
17
Lesbarkeit (2)
Was bedeutet das:
listen = (1..5).to_a.map {|i| "#{i} tes Element"}
In grails für
for (int i=1;i<=5;i++){
liste[i] = i +‚ .tes Element';
}
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
18
Lesbarkeit vor Effizienz!
Speziell bei wechselnden Teilnehmer
Knappe Skripttexte schwer lesbar und nachvollziehbar
Zeitaufwendig, sich in knappe Skripte anderer einzuarbeiten
Skriptsprachen, können zu unlesbaren Quelltexten
„verleiten“
Bei vielen Beteiligten: besser JAVA statt Skripte
Daher auch in IMAGINATION Entscheidung für JAVA
basierendes Framework
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
19
Model View Controller vs. Event basiertem Framework (1)
Ablauf eines http-request / response mit MVC
http request kommt an, Framework ruft Controller auf
Controller sucht (meist auf Konfigurationsdateien basierend)
passende Action aus
Request Parameter werden in ein Action Bean geschrieben
und validiert, http Request, Action Bean und Response
werden an Action Klasse weitergegeben
Action Class setzt Anwendungslogik um
Action Class ruft Controller auf, um View zu generieren
Controller ruft View auf (z.B. JSP Seite), um Ausgabe zu
generieren
Rückgabe der Response
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
20
Model View Controller vs. Event basiertem Framework (2)
Eventbasiert: http-request / response
Framework erhält http-Request, ermittelt verantwortliche Seiten
und Komponenten
Request wird in Event übersetzt (z.B. onSubmit.). Jede
Komponente hat eigenen Eventhandler (vgl. swing).
Jede von Event betroffene Komponente führt Event aus
(Anwendungslogik) und rendert sich selbst.
Framework gibt response zurück
Möglichkeiten mit eventbasiertem Frameworks
Abstraktion von request / response Prinzip von http =>
objektorientierte Erstellung von wiederverwendbarek Komponenten
möglich
Eventbasiertes Prinzip ermöglicht direkte Integration von AJAX für
Events der Komponenten, weniger Konfiguration und meistens
weniger Quelltext (im Vergleich von Wicket zu MVC basierenden
Frameworks wie Struts , JSF)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
21
Auswahl des Web-Frameworks
Beispiel: ImageNotion
ImageNotion enthält viele Events, die einzelne
Komponenten aktualisieren, z.B.
Layoutbilder anzeigen
Annotation von Bildern und Bildteilen
Ontologieerstellung
=> Ideal ist ein eventbasiertes Rahmenwerk
Strikte Trennung von Anwendung und Darstellung nötig
Umfangreicher AJAX – Support nötig
=> Auswahl Web Framework: Wicket 1.3
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
22
Apache Wicket
Features
Vergleich mit anderen Frameworks
Wicket 1.4
URL: http://wicket.apache.org/
Aktuelle Version: 1.4
Offizielles Apache Projekt seit Juli 2007
Wiki: http://cwiki.apache.org/WICKET/
Dokumentation und Beispiele
http://www.wicket-library.com/
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
24
Features von Wicket (1)
Entwicklung der Anwendung mit JAVA
Alleinige Verwendung von JAVA und HTML
Kein erlernen von Konzepten / Sprachen oder Funktionen
nötig
Keine XML Konfigurationen nötig (ausser web.xml für Servlet
Container)
weniger Fehlerquellen und weniger Entwicklungsaufwand
Eventbasiertes Komponentenmodell basierend auf
JAVA-Objekten
Eventhandler für Komponenten wie in SWING
Ermöglicht Erstellung von wieder verwendbaren
Komponenten
Einfache und direkte Integration von AJAX möglich
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
25
Features von Wicket (2)
Strikte Trennung von Darstellung und Anwendung
Sämtliche Darstellung basiert auf XHTML
Strikte Trennung von Anwendungsentwicklung mit JAVA
Objekten und Seitendesign mit HTML
Integration von Komponenten mit HTML Tags
(<wicket:id=“..“ .. >)
Abstraktion von Basistechnologie http
Seitenversionierung, ermöglicht unter anderem „Back Button
Support“ für Formulare (vermeidet wiederholtes Senden und
unerwünschte Seiteneffekte von POST requests)
Automatisches Sessionhandling: Typesafe Session - keine
manuelle Sessionverwaltung nötig
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
26
Features von Wicket (3)
Internationalisierung
einfache Integration von mehreren Sprachen basierend auf
i18n Standard
Support
sehr guter Support durch die Mailingliste, kurze
Reaktionszeiten auf Anfragen
Open Source
Quelltextanalyse ermöglicht Suche nach Bugs in Framework
oder Deaktivierung von nicht benötigten Funktionen
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
27
Wicket im Vergleich mit anderen Frameworks
Wicket ermöglicht die komplette Programmierung der
Anwendung in JAVA, ohne Verwendung weiterer
Konfigurationsfiles (JSF, Struts) oder domainspezifischen
Sprachen , ist somit auch einfacher erlernbar.
Umfangreicher AJAX Support bereits im Framework
integriert, keine Erweiterungen hierfür notwendig (z.B. Ajax in
JSF Standard nicht möglich, nur mit Erweiterungen wie z.B.
Ajax4JSF
Saubere Trennung von Anwendung und Darstellung.
Struts verwendet JSP Seiten, in JSF entsprechende Trennung
nur durch Einsatz von Faceletts (SEAM) möglich
Sehr agiles Entwicklerteam, das (ungewohnt) direkt auf
Anforderungen der Nutzer des Frameworks reagiert und
Wünsche umsetzt.
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
28
Wicket Tutorial
Aufbau einer Bildsuchmaschine
Struktur
Startseite
Login
Bildsuche
Registrierung
Bildergebnis
Anzeige Layoutbild
Upload Bilder
Datenhaltung
Bilddateien
Bildbeschreibung
(Keywords, Bildnamen)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
Userdaten
30
Download und Installation
1. Download und Installation von Maven
2. MySql Server installieren, neue Datenbank und User, z.B.
Datenbank „wickettutorial“, User/Pass: wicket
3. Tutorials unter SVN Adresse (z.B. mit Tourtoise SVN)
https://svn.awalter.info/docs/vorlesung/webportale/wicke
t-tutorial
Benutzer: tutorial , Passwort: wicket
4. Konsole starten, in SVN Verzeichnis in Unterordner
workspace wechseln
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
31
Maven (1)
Profiles.xml editieren
Dient zur Anpassung der Konfiguration an eigenes System
Ermöglicht Betrieb des gleichen Maven Projects auf unteschiedlichen Systemen, z.B. lokal,
Continous integration server, etc
Hier
Zugangsdaten mysql
Eigene Verzeichnisdaten
<properties>
<jdbc.uri>jdbc:mysql://localhost:3306/wickettutorial</jdbc.uri>
<jdbc.username>wicket</jdbc.username>
<jdbc.password>wicket</jdbc.password>
<setup.imageArchiveDirectory>#directory#/workspace/searchimpl/src/main/webapp/site/img/ar
chive</setup.imageArchiveDirectory>
<setup.imageURL>http://localhost:8080/image/</setup.imageURL>
<setup.thumbnailSize>150</setup.thumbnailSize>
<setup.layoutSize>450</setup.layoutSize>
</properties>
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
32
Maven (2)
Pom.xml Datei in Verzeichnis „Workspace“
Definiert die Abhängigkeiten des Projekts, z.B. Wicket in 1.3.5 soll verwendet werden
<properties>
<wicket.version>1.3.5</wicket.version>
…
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>${wicket.version}</version>
</dependency>
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
33
Maven (3)
Pom.xml in „searchimpl“
<packaging>war</packaging>
Output soll „War“ File sein, zur Integration in beliebigem
Servlet-Container
Initialisierung von Maven
Mit Konsole auf „workspace“ Verzeichnis wechseln
„mvn test“
(lädt alle benötigten JAR Files, dauert etwas)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
34
Integration in Eclipse Version 3.2 oder 3.3
Eingabe
„mvn eclipse:eclipse“
Eclipse starten
Workspace importieren:
File -> Import ->
General ->
Existing Project into Workspace :
Auf Verzeichnis „workspace“
des Tutorials wechseln
Ok
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
35
Eclipse (2): M2 Repo Variable setzen
Eclipse benötigt Information zu Repository von Maven
Ort: Verzeichnis von Maven/repo
Konfiguration in Eclipse
Window->Preferences->JAVA->
Build Path->Classpath Variables :
Add new
Name: M2_REPO
Directory: Repo von Maven
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
36
Testen der Konfiguration und Datenbankinstallation
Project enthält JUnit Test, dass Konfiguration testet und
bei Erfolg alle benötigten Tabellen und Daten installiert
Starten
Run -> JUNIT -> New
Run a single test in
„searchimpl“
Test class:
„CreateAndPersistanceTest“
„Apply“; „Run“
Bei Fehlern
zurück zu Maven(1)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
37
Wicket Tutorial
Persistence und ORM mit Spring
Beans erstellen
Ort: info.awalter.tutorial.beans
Beans: Model der Anwendung, Datenintegration
ApplicationSetup
String imageArchiveDirectory;
int thumbnailSize;
int layoutSize;
int imagesPerPage;
String imageURL;
Enthält Setup Informationen für die Anwendung
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
39
ImageData: Bildinformationen
ImageData
Enthält Informationen zu den anzuzeigenden Bildern:
int imageid;
String imagename;
String keywords;
String outputType; // thumb: small image | layout: big size
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
40
Beans : IndexWord und SearchRequest
IndexWord
Dient zum Speichern von Index-Wörtern
Ermöglicht Autocomplete bei Suchanfragen
String indexword;
SearchRequest
Nimmt eine Suchanfrage vom Frontend entgegen
String searchword;
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
41
Bean: User
User
Speichert die Informationen eines Users
Hier: nur username, password, email
private
private
private
private
private
int userId;
String sessionId;
String username;
String password;
String email;
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
42
Persistence: Tabellen in Datenbank erstellen
User und Bilddaten müssen langfristig gespeichert
Hier: Mapping der Objekte auf relationales DBMS mysql
Tabelle : Registeredusers
UserId` INTEGER
`SessionID` VARCHAR(100)
`Username` VARCHAR(45)
`Password` VARCHAR(45),
`Email` VARCHAR(100)
INDEX: UNIQUE `UniqueUsername`(`Username`))
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
43
Persistence (2)
Tabelle : images
`imageid` INTEGER
`imagename` VARCHAR(45)
`keywords` VARCHAR(255)
PRIMARY KEY(`imageid`)
INDEX `keywordindex`(`keywords`) <- Volltextindex
Tabelle keywordindex
`keyword` VARCHAR(50) DEFAULT '',
UNIQUE uniquekeyword(`keyword`)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
44
Spring: Object Relational Mapping (ORM)
Spring Framework: http://www.springframework.org/
Inversion of control: Anwendung kennt nur die Interfaces,
Spring initiert die benötigten Implementierungen
Ermöglicht Abstraktion von DBMS (durch untersch.
Implementierungen)
Direkter Aufruf der entsprechenden Objekte aus Anwendung
möglich (injection)
Initiierung von Objekten (z.B. ApplicationSetup)
Integriertes ORM
Vorgehen
Interface erstellen
Implementierung
Setup Spring: applicationContext.xml
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
45
Methoden für User: UserManagerDao
Ort: info.awalter.tutorial.persistence.user
Interface UserManagerDao
public List getUsers();
public User getUserByUsernamePassword(String username, String
password);
public boolean changePassword(int UserId, String password);
public User updateUserData(User user);
public User getUserByCookieId(String cookieId);
public User getUserByUserId(int userid);
public boolean setUserSessionId(int userid, String cookieId);
public User createUser(User user);
public boolean deleteUser(User user);
public boolean isUsernameInList(String username);
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
46
UserManagerDao: Spring setup
applicationContext.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroymethod="close">
<property
name="driverClassName"><value>org.gjt.mm.mysql.Driver</value></property>
<property name="url"><value>${jdbc.uri}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
<property name="initialSize"><value>10</value></property>
<property name="maxActive"><value>10</value></property>
<property name="maxIdle"><value>20000</value></property>
</bean>
Name des Beans in Anwendung
<bean id="persistenceuser"
class="info.awalter.tutorial.persistence.user.UserManagerDaoJdbc">
<property name="dataSource"><ref local="dataSource"/></property>
</bean>
Zu verwendende Implementierung
Zu verwendende Datenquelle
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
47
Methoden für ImageData
Ort: info.awalter.tutorial.persistence.images
Interface ImageManagerDao
public
public
public
public
public
List getAllImages();
List searchImages(String keywords);
ImageData insertImage(ImageData i);
boolean updateImage(ImageData i);
boolean deleteImage(ImageData i);
public byte[] loadImageFile(ImageData i, String outputType );
public boolean saveImageFile(ImageData i,InputStream input);
public boolean deleteImageFile(ImageData i);
public List getAllIndexKeywords();
public List getAllIndexKeywordsStartingWith(String start);
public boolean insertIndexKeyword(String keyword);
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
48
Persistence: Zusammenfassung
Beans erstellen: Model in der Webanwendung
Datenbank erstellen
Framework für ORM verwenden
Hier: Spring
Alternativ: Hybernate
(speziell wenn Transaktionen benötigt werden)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
49
Wicket Tutorial
Anwendung erstellen
Erstellen einer Wicket Anwendung
Ort: info.awalter.tutorial.application
SearchApplication:
In Wicket: Setup der ganzen Anwendung direkt in JAVA
(statt in XML Konfigurationsdateien, z.B. JSF)
Authorisierung
SearchAuthorizationStrategy storeAuthStrategy =
new SearchAuthorizationStrategy();
Ort der HTML-Dateien
Standard: im gleichen Verzeichnis wie JAVA File
Anpassung: alternativer Ort
resourceSettings.addResourceFolder( "site/html" );
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
51
Anwendung (2)
SearchApplication (Fortsetzung)
Seiten auf feste Verzeichnisse mounten
this.mountBookmarkablePage("/login", Login.class);
Home Page der Anwendung festlegen
public Class getHomePage() {
return Home.class;
}
Spring Injection initialisieren
addComponentInstantiationListener(new
SpringComponentInjector(this));
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
52
Anwendung in Servlet Container initialisieren
Initialisierungen mit web.xml
(Standard in Servlet Container)
Ort: src/main/webapp/WEB-INF/web.xml
Setup von Spring und Context Listener
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
Wicket Anwendung initialisieren
<init-param>
<param-name>applicationClassName</param-name>
<param-value>info.awalter.tutorial.application.SearchApplication</param-value>
</init-param>
Mapping der Anwendung auf Hauptverzeichnis:
localhost:8080/
<filter-mapping>
<filter-name>search</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
53
Anwendung: Authorisierung
Ort: info.awalter.tutorial.application
SearchAuthorizationStrategy implements IAuthorizationStrategy
if (SecuredSearchPage.class.isAssignableFrom(componentClass))
…
Interface, dass zugangsbeschränkte
Seiten implementieren
if (session.isUserLoggedIn())
{
return true; // User ist authorisiert
}
// sonst weiterleitung auf
Login login=new Login();
throw new RestartResponseAtInterceptPageException(login.getClass());
Authorisierung mit Interfaces
Session hält Userinformationen: Login setzt isUserLoggedIn auf true für berechtigte
User
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
54
Context eines Users
SearchSession
Hält Zustände eines Users
SessionId (Identifikation des Users über http)
Locale: bevorzugte Sprache des Users
Authorisierungsinformationen
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
55
Home Page: Die Startseite der Anwendung
Ort: org.apache.wicket.markup.html.WebPage
Home extends PageTemplate
Templating
Ermöglicht einheitlichen Look aller Seiten
Logo
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
Top Menu
56
Templates
Ort: src/main/webapp/site/html/info/awalter/tutorial/pages
PageTemplate.html
Definiert einheitliches Layout der Seite
HTML Markup zur Erweiterung der Seite:
<wicket:child>
Here comes the child content
</wicket:child>
Inhalt der erweiterten Seiten wird dort eingefügt.
HTML Markup in erweiterten Seiten, z.B. in Home.html
<wicket:extend>
… html markup
<wicket:extend>
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
57
Wicket Markups
Verbindung von HTML und Anwendung
Alle Komponenten bekommen eine wicket id (String).
Dieser wird in HTML Text an entsprechenden Stellen
platziert.
HTML Marken für
Komponenten: <span wicket:id=„komponentenid“/>
Links:
<a wicket:id="linkToHome" class="standardlink">Über</A>
Aufruf in Wicket, z.B. für Link
BookmarkablePageLink linkToHome = new
BookmarkablePageLink("linkToHome", Home.class);
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
58
Internationalisierung
Unterstützung bei Seiten / Templates
Dateien werden mit entsprechenden Endungen des
Ländercodes versehen, z.B:
PageTemplate_de.html : deutsche Version
PageTempate.html : Default = englische Version
Unterstützung für Ausgaben in Anwendungen
Propertie-Files mit Namen entsprechend der Klasse +
Sprachendung, z.B. home_de.properties
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
59
Page Template
Funktionen
<span wicket:id="toparea„/>
Lädt Komponente „SmallLoginForm“, wenn der User unregistriert
ist, sonst das Suchmenü
Schreibt Seitentitel: Abstrakte Methode getPageTitle();
Konkrete Klassen schreiben ihren Seitentitel in Methode,
PageTemplate füllt Labelkomponente für Seitentitel
Erstellt Links auf statische Seiten
Wichtigste Arten von Links in wicket:
Link : mit Event „onClick“: Links die nur während einer Session gültig
sind
BookmarkablePageLink:
Links die man auch Bookmarken kann
(entspricht „mount“ Befehl in SeachApplication)
AjaxLink:
löst ein AjaxEvent aus, gibt eine Componente zurück
an Ajax Request
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
60
Home
Funktionen der Startseite
Anzeige eines zufällig geladenen Bildes
Anzeige eines statischen Textes
Alle statischen Seiten (also auch About, etc) werden von
StaticTemplate erweitert
=> immer Anzeige des zufällig erzeugten Bildes
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
61
Erstellung eigener Komponenten
info.awalter.tutorial.pages.user.SmallLoginPanel
Eigene Komponenten: extends Panel
HTML Markup:
<wicket:panel>
… HTML Inhalt des Panels
</wicket:panel>
Komponente dann an beliebigen Stellen in Seite einbindbar.
Seite Home nun darstellbar
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
62
Starten der Anwendung aus Eclipse
Merve Tomcat Plugin installieren
http://merve.sourceforge.net/updates/eclipse-3.2/
Alternativ: mvn jetty:run
Run->Merve Tomcat Plugin -> New
Context Root Dir: searchimpl/src/main/webapp/
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
63
Startseite der Demo Anwendung
Komponente: SmallLoginPanel
Internationalisierung
Komponente: DisplayRandomImage
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
64
Formulare in wicket
Formulare nehmen User-Eingaben entgegen
Ereignis: onSubmit()
Hauptkomponenten: TextField, Password, TextArea, …
Daten an Formulare binden
Prinzip: Jede Formularkomponente bekommt Signatur einer
Bean-Variablen oder einer Variablen in Klasse
Eingaben werden an diese Variable gebunden
Beispiel: TextField user = new TextField("username");
Bean oder Klasse benötigt Variable „username“ und
Methoden getUsername, setUSername
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
65
Formulare: Modelle in Wicket
PropertyModel: bindet eine Methode, z.B. für Labels
geeignet
new PropertyModel(this,"pageTitle") (aus PageTemplate)
CompoundPropertyModel: bindet alle get/set
Methoden einer Bean oder Klasse
final User userbean=new User();
form.setModel(new CompoundPropertyModel(userbean));
Siehe z.B. in Login, Register
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
66
Validatoren für Usereingaben
Automatisches validieren von Usereingaben vor Abruf der
onSubmit() Methode eines Formulares
Ablauf (z.B. in info.awalter.tutorial.pages.user.Register)
1. FeedbackPanel Componente einbinden in Seite
add(new FeedbackPanel("feedback"));
-> Wicket schreibt automatischFeedback in diesen Panel
2. Validatoren an Formelemente binden
(aus org.apache.wicket.validation.validator.)
EmailAddressValidator validiert E-Mail Format
Eingabe erforderlich: formelement. setRequired(true);
Mindestlänge erforderlich: MinimumLengthValidator
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
67
Ajax Integration für Formularelemente
An Formularelemente können Events gebunden werden,
die mittels Ajax abgearbeitet werden.
Diese ermöglichen z.B. Autocomplete oder direkte
Information der User über Fehleingaben
Beispiel Reaktion auf Fehleingaben: Register
user.add(new
AjaxFormComponentUpdatingBehavior("onchange")
{
target.addCompontent(…);
}
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
68
Beispiel: Registrierungsformular
Ort: info.awalter.tutorial.pages.user.Register
1. Bean User wird als CompoundPropertyModel gebunden
2. Formular enthält Textfelder username, email und Passwortfeld
password
3. Minlength Validatoren für username / password: 4
Email Validator für Feld email
4. onSubmit Event: Wicket validiert Eingaben, bricht bei unkorrekten
Eingaben ab und sendet Fehlerstring an FeedbackPanel
5. onSubmit: falls alle Eingaben richtig sind wird onSubmit Methode des
Formulars abgearbeitet
6. Methode prüft, ob username bereits existiert, falls nicht wird bean an
Spring bean zur Speicherung gesendet
userdao.createUser(userbean);
7. User wird in Session eingeloggt
8. Weiterleitung auf Startseite
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
69
Login Formular
Alle Seiten, die durch unberechtigte User nicht betreten
werden dürfen implementieren Interface
SecuredSearchPage, z.B. LayoutPage
Wicket leitet bei entsprechenden unberechtigten Aufrufen
den Nutzer an Login Formular weiter
Login Formular hat (vgl. Register bean user als model).
Nimmt username / password entgegen, wenn user
vorhanden
userdao.getUserByUsernamePassword
wird user in Session gesetzt (Authorisiert)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
70
UserMenuPanel: Starten von Suchanfragen
Übermittlung der Suchanfragen mit Formular
Textfeld für Suchanfragen enthält Autocomplete Funktion
Umsetzung
Verwendung der Wicket-Komponente
AutoCompleteTextField searchword = new
AutoCompleteTextField("searchword")
Funktion: sendet „onkeyup“ Events per Ajax
Nimmt Eingabe, z.b. input = „b“ entgegen
Suche entsprechender Wörter mit imagedao
imagedao.getAllIndexKeywordsStartingWith(input);
Rückgabe der passenden Keywords als Liste
Schnell integriert, keine JAVA-Script Programmierung nötig
Bei onSubmit: Aufruf der Seite SearchResultPage mit Suchanfrage
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
71
SearchResultPage: Generierung von Suchergebnisseiten
SearchResultPage Komponenten
Anzeige von 8 Bildern pro Seite als Thumbnailtabelle
Vor / Zurück Navigation
Ruft die nächsten Seite per Ajax auf
Aktualisiert nur die Thumbnailtabelle
AjaxLink previousPage = new AjaxLink("previousPage"){
public void onClick(AjaxRequestTarget target)
{
// set currentpage +1 :
setCurrentPage(getCurrentPage()-1);
// remove current content from thumbnailtable
thumbnailtable.removeAll();
// set table and return to ajaxrequest
target.addComponent(getThumbnailTable());
};
Anzeige der Treffermenge: statisch
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
72
Generierung der Thumbnailtabelle
Ort: info.awalter.tutorial.pages.search.thumbnailtable
Verwendung von RepeatableView
ImageTableRow: generiert Zeilen
<TABLE wicket:id="tablerow" BORDER=0 >
<tr>
</tr>
</TABLE>
ImageTableCol: generiert Spalten
<wicket:panel>
<td wicket:id="tablecol" width="200" valign=bottom>
</td>
</wicket:panel>
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
73
UploadNewImages: neue Bilder aufladen
UploadNewImages
Nutzung der Wicket Komponente MultiFileUploadField und
UploadProgressBar aus Wicket Extension Bibliothek
Bilder aufladen nur über normale Formulare möglich!
onSubmit():
Nimmt Bilddateien entgegen
image=imagedao.insertImage(image);
prüft, ob Bild mit Dateinamen bereits existiert.
Falls ja kommt Fehlermeldung zurück
imagedao.saveImageFile(image, upload.getInputStream());
speichert die Bilddatei in Archivverzeichnis
Rückgabe der Erfolgs / Fehlermeldung als RepeatableView aus
Labels bestehend
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
74
Logout
Logout
Beendet Session des Users
this.getSession().invalidate();
Entfernt alle Zustände der Usersession
Login beendet
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
75
Testen von Wicket Anwendungen: wickettester
WicketTester
Ermöglicht Durchführung von JUnit Tests für Wicket-Seiten
ohne jedesmal den Servletcontainer starten zu müssen
Auch Wicket Tests mit Spring-Integration möglich
Siehe hierzu: TestSearchApplication (Context muss manuell
initiiert werden)
Beispiel: WicketApplicationTest
Ort: info.awalter.tutorial.wickettest
Aufruf einer Seite:
tester.startPage(home);
tester.assertRenderedPage(home.getClass());
=> prüft, ob Seite Home richtig erstellt werden kann
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
76
Wickettester (2)
Test von Formularen
Login login=new Login();
tester.startPage(login);
tester.assertRenderedPage(login.getClass());
// set form values: use FormTester
FormTester form = tester.newFormTester("loginForm");
form.setValue("username", "fzi");
form.setValue("password", "web");
// submit form
form.submit();
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
77
Zusammenfassung
Gezeigt wurde mit dieser Demo-Anwendung
Build-Kontrolle
Integration von Daten mittels Beans und Springframework
Integration von Spring in Wicket
Einheitliches Layout mit Templating und
Internationalisierung
Integration von eigenen Komponenten und Nutzung von
Standardkomponenten
Formulare erstellen, Datenbindung von Beans, Validierung
Integration von AJAX-Funktionen
Testen von Wicket-Anwendungen
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
78
Exkurs: ImageNotion
In Demo Anwendung: Suche „Anna“ zeigt unterschiedliche
Sachverhalte (Hund namens Anna, Frau namens Anna)
Gewünscht
Unterscheidung bereits bei Anfrage
Ausblick
Lösung durch semantische Techniken (Vorlesungen A.
Schmidt)
Umsetzung für Bilder: ImageNotion (demo)
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
79
Quellen
Wicket Homepage: http://wicket.apache.org/
Wicket Erweiterungen
http://www.wicket-library.com
Vergleich Wicket / Struts
http://cwiki.apache.org/WICKET/struts.html
Vergleich Wicket / JSF
http://ptrthomas.wordpress.com/2007/05/14/a-wicketuser-tries-jsf/
Vergleich Wicket / Tapestry
http://agileskills2.org/blog/2007/09/my_thoughts_on_the_
differences.html
Informationsintegration & Web-Portale
WS
2007/08
WS
2009/10
80