2. Kapitel - JBoss Seam - Die Web-Beans

Transcrição

2. Kapitel - JBoss Seam - Die Web-Beans
JBoss Seam
Kapitel 2: Seam als modernes
Komponenten-Framework
Max Mustermann
Uni Musterhausen
Fachbereich Informatik
Wintersemester 2008/09
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
1 / 41
Grundlage der Folien
Bernd Müller
JBoss Seam
Die Web-Beans-Implementierung
Hanser
ISBN 978-3-446-41190-6
34,90 Euro
Bei Amazon kaufen
Home-Page:
www.webbeans.eu
Überblick
I
Java-EE 5
I
I
I
I
I
I
als Reaktion auf Kritik an J2EE 1.4 (und früher)
I
I
I
I
Servlets 2.5 (JSR 154)
JSP 2.1 (JSR 254)
JSF 1.2 (JSR 252)
EJB 3.0 / JPA 1.0 (JSR 220)
und einige mehr
verwendet POJO
Annotationen, weniger XML, insgesamt weniger aufwändig
verwendet Dependency-Injection
Seam geht weiter
I
I
integriert EJB und JSF in einheitlichem Komponentenmodell
und vereinfacht die Verwendung von Java-EE 5 (EJBs, JPA und JSF)
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
3 / 41
2.1 JSF und Facelets
JSF und Facelets
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
4 / 41
2.1 JSF und Facelets
Facelets
I
JSF ist renderunabhängig, Default HTML auf Basis von JSPs
I
Facelets einfacher und mächtiger als JSPs (und mit JSF 2.0 Standard)
I
hervorzuheben: Template-Mechanismus für Seiten
I
Tags: <ui:component>, <ui:composition>, <ui:debug>,
<ui:decorate>, <ui:define>, <ui:fragment>, <ui:include>,
<ui:insert>, <ui:param>, <ui:remove>, <ui:repeat>
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
5 / 41
2.2 EJBs und JPA
EJBs und JPA
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
6 / 41
2.2 EJBs und JPA
Enterprise JavaBeans (EJB)
I
Session-Beans
I
I
Stateless (@Stateless)
Stateful (@Stateful)
I
Entity-Beans (@Entity)
I
Message-Driven-Beans (@MessageDriven)
verwenden wir nicht
I
alle im Package javax.ejb
Literatur:
I
I
I
Bill Burke, Richard Monson-Haefel. Enterprise JavaBeans 3.0. O’Reilly,
2006.
Bernd Müller, Harald Wehr. Java-Persistence-API mit Hibernate.
Addison-Wesley, 2007.
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
7 / 41
2.2 EJBs und JPA
Enterprise JavaBeans II
I
I
I
I
I
I
Session-Beans definieren Schnittstelle zur Client-Anwendung und
realisieren Anwendungsfälle und Geschäftsprozesse
z.B. neues Konto (Entity) anlegen, Überweisung durchführen
zustandslose Session-Beans besitzen keinen für den Client sichtbaren
Zustand, der Container kann sie daher beliebigen Clients zuweisen
(Pool!)
zustandsbehaftete Session-Beans besitzen einen solchen Zustand
in Java-EE typischerweise an HTTP-Session gebunden, Seam kennt
weitere Kontexte
eine Session-Bean kann
I
I
I
ein remote Interface implementieren
ein lokales Interface implementieren (@Local)
Namenskonventionen:
I
I
I
Java-EE-Tutorial Bean“
”
Seam-Doku/Beispiele Action“
”
wir Handler“und HandlerLocal“
”
”
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
8 / 41
2.2 EJBs und JPA
Enterprise JavaBeans III
I
Entity-Beans:
I
I
I
persistente Business-Objekte
über JPA-Annotationen auf Datenbank abgebildet
@Entity und @Id für einfache Fälle bereits ausreichend
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
9 / 41
2.3 Seam-Komponenten
Seam-Komponenten
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
10 / 41
2.3 Seam-Komponenten
Ziele
I
Verwendung von POJOs anstatt Interfaces implementieren oder von
Oberklassen erben zu müssen
I
Minimierung von XML-Konfigurationen (XML-Hölle)
I
JSF ist ein Komponenten-Framework, EJB ist ein
Komponenten-Framework, Seam verbindet beide (plus vieles mehr)
I
Komponenten werden von Seam verwaltet
I
Abhängigkeiten werden durch Dependency-Injection bzw. Bijection
aufgelöst
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
11 / 41
2.3 Seam-Komponenten
Neue Kontexte
I
Stateless
Komponenten dieses Kontextes können keinen Zustand verwalten.
I
Event
Komponenten dieses Kontextes halten ihren Zustand während der
Bearbeitung einer einzelnen JSF-Anfrage.
I
Page
Komponenten dieses Kontextes halten ihren Zustand bzgl. einer
gerenderten JSF-Seite.
I
Conversation
Komponenten dieses Kontextes halten ihren Zustand über eine
Konversation, d.h. eine Reihe von JSF-Anfragen.
I
Session
Komponenten dieses Kontextes halten ihren Zustand in der
entsprechenden HTTP-Session.
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
12 / 41
2.3 Seam-Komponenten
Neue Kontexte II
I
Business-Process
Komponenten dieses Kontextes halten ihren Zustand über einen
länger andauernden Geschäftsprozess.
I
Application
Komponenten dieses Kontextes sind statisch und entsprechend global.
Besonders hervorzuheben:
I
Konversationen (kleiner als Session)
I
Geschäftsprozesse (mehrere involvierte Benutzer, überleben
Ein-/Ausloggen und Server-Neustart)
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
13 / 41
2.4 Das Anwendungsbeispiel
Das Anwendungsbeispiel
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
14 / 41
2.4 Das Anwendungsbeispiel
Anwendungsbeispiel
I
zur Einführung ein kleines Beispiel
I
Online-Banking
I
einfache Anwendungsfälle
I
einfache Daten
I
jedem bekannt
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
15 / 41
2.4 Das Anwendungsbeispiel
Die Daten (Entities)
Attributes
Attributes
Attributes
Operations
Operations
Operations
Attributes
Attributes
Attributes
Operations
Operations
Operations
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
16 / 41
Stammdaten
< h:form id = " stammdaten " >
< s:validateAll >
< f:facet name = " afterInvalidField " >
< s:div styleClass = " errors " >
< h:graphicImage url = " / images / error_small . png " / >
< s:message / >
</ s:div >
</ f:facet >
< div class = " usrFormEntry " >
< h:outputLabel for = " nachname " styleClass = " usrFormLabel " >
Anrede:
</ h:outputLabel >
< h:selectOneMenu id = " anrede " value = " #{ kunde . geschlecht } "
styleClass = " usrFormValue " >
< f:selectItem itemLabel = " Frau " itemValue = " w " / >
< f:selectItem itemLabel = " Herr " itemValue = " m " / >
</ h:selectOneMenu >
</ div >
...
Stammdaten II
...
< div class = " usrFormEntry " >
< h:outputLabel for = " nachname " styleClass = " usrFormLabel " >
Vorname:
</ h:outputLabel >
< s:decorate >
< h:inputText id = " vorname " value = " #{ kunde . vorname } "
required = " true " styleClass = " usrFormValue "
</ s:decorate >
</ div >
...
</ s:validateAll >
< h:commandButton action = " #{ stammdatenHandler . speichern } "
value = " Speichern " styleClass = " usrFormSubmit "
</ h:form >
2.4 Das Anwendungsbeispiel
Analyse
I
ganz normale JSF-Seite mit Ausnahmen:
I
I
<s:validateAll>
<s:decorate>
I
<s:validateAll> validiert alle Eingabekomponenten anhand der
Validierungsbedingungen der Modell-Properties
(z.B. @Length, siehe Entity )
I
<s:decorate> dekoriert bei einem Validierungsfehler die
Eingabekomponente (Abbildung folgt)
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
19 / 41
Seite mit Menü- und Fußzeileneinbindung
<! DOCTYPE html PUBLIC
" - // W3C // DTD XHTML 1.0 Transitional // EN "
" http: // www . w3 . org / TR / xhtml1 / DTD / xhtml1-transitional . dtd " >
< html xmlns = " http: // www . w3 . org /1999/ xhtml "
xmlns:ui = " http: // java . sun . com / jsf / facelets "
xmlns:h = " http: // java . sun . com / jsf / html "
xmlns:f = " http: // java . sun . com / jsf / core "
xmlns:s = " http: // jboss . com / products / seam / taglib " >
< head >
< title > Stammdaten </ title >
</ head >
< body >
< ui:include src = " menu . xhtml " / >
< div id = " cTitle " > Stammdaten </ div >
< div id = " ... " >
< h:form id = " stammdaten " >
...
</ h:form >
</ div >
< ui:include src = " footer . xhtml " / >
</ body >
</ html >
2.4 Das Anwendungsbeispiel
Darstellung Stammdaten
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
21 / 41
2.4 Das Anwendungsbeispiel
Darstellung Stammdaten mit Fehlermeldung
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
22 / 41
Entity Kunde
@Entity
@Scope ( SESSION )
@Name ( " kunde " )
public class Kunde implements Serializable {
private
private
private
private
private
private
private
private
Integer id ;
String vorname ;
String nachname ;
Date geburtsdatum ;
Character geschlecht ;
String kundennummer ;
String passwort ;
Set < Konto > konten = new HashSet < Konto >();
public Kunde () {
super ();
}
...
2.4 Das Anwendungsbeispiel
Analyse
I
@Entity: JPA-Annotation für Persistenz
I
Convention over Configuration oder Configuration by Exception:
sinnvolle Default-Annahmen für Persistenz:
I
I
I
Klassen- gleich Tabellenname
alle Properties persistent, selber Spaltenname (nicht persistent:
@Transient)
einfaches Typ-Mapping
I
@Scope: Seam-Kontext
I
@Name: Name der Seam-Komponente
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
24 / 41
Entity Kunde II
...
@Id
@GeneratedValue ( strategy = GenerationType . IDENTITY )
public Integer getId () {
return this . id ;
}
public void setId ( Integer id ) {
this . id = id ;
}
@Column ( nullable = false )
@Length ( min = 3 , max = 30 ,
message =
" Vorname muss zwischen 3 und 30 Zeichen lang sein " )
public String getVorname () {
return this . vorname ;
}
public void setVorname ( String vorname ) {
this . vorname = vorname ;
}
2.4 Das Anwendungsbeispiel
Analyse
I
@Id: Primärschlüssel in Datenbanktabelle
I
wenn Getter/Setter annotiert, erfolgt für alle Propertes Zugriff über
Getter/Setter
I
@GeneratedValue: Primärschlüssel soll generiert und nicht durch
Anwendung vergeben werden. Verschiedene Generierungsarten
möglich.
I
@Column: JPA-Annotation, hier: nicht null
I
@Length: Hibernate-Validator-Annotation mit offensichtlicher
Semantik
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
26 / 41
Entity Kunde III
...
@Column ( nullable = false )
@Temporal ( TemporalType . DATE )
public Date getGeburtsdatum () {
return this . geburtsdatum ;
}
public void setGeburtsdatum ( Date geburtsdatum ) {
this . geburtsdatum = geburtsdatum ;
}
@Column ( nullable = false , unique = true )
public String getKundennummer () {
return kundennummer ;
}
public void setKundennummer ( String kundennummer ) {
this . kundennummer = kundennummer ;
}
...
2.4 Das Anwendungsbeispiel
Analyse
I
@Temporal: java.util.Date Zeitstempel mit Millisekunden, muss
auf verschiedene SQL-Datentypen abgebildet werden
I
möglich sind DATE, TIME, TIMESTAMP
I
@Column(..., unique = true): Constraint Spalte hat keine
Duplikate
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
28 / 41
Entity Kunde IV
...
@OneToMany ( mappedBy = " kunde " , cascade = CascadeType . ALL )
public Set < Konto > getKonten () {
return this . konten ;
}
public void setKonten ( Set < Konto > konten ) {
this . konten = konten ;
}
...
2.4 Das Anwendungsbeispiel
Analyse
I
@OneToMany: 1:n-Beziehung zur Klasse Konto
I
mappedBy: Property für Beziehung (in DB Fremdschlüsselspalte)
I
cascade: welche Persistenzoperationen sollen automatisch
weitergegeben werden? Hier: alle
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
30 / 41
2.4 Das Anwendungsbeispiel
Erleichterungen für Entwicklung und Deployment
I
Generierung des DB-Schemas beim Deployment, falls erwünscht. Hier
für HSQLDB:
create table Kunde (
id integer generated by default as identity ( start with 1) ,
vorname varchar (30) not null ,
nachname varchar (30) not null ,
geburtsdatum date not null ,
geschlecht char (1) not null ,
kundennummer varchar (255) not null ,
passwort varchar (255) not null ,
primary key ( id ) ,
unique ( kundennummer )
)
I
Hibernate (im JBoss-AS) lädt beim Deployment Datei import.sql,
falls vorhanden. Testdaten!!!
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
31 / 41
2.4 Das Anwendungsbeispiel
Wie finden GUI und Persistenz zueinander?
I
Seam verwalten Netz von Abhängigkeiten zwischen Komponenten
I
existiert eine Komponente noch nicht, wird sie erzeugt
I
es können auch anwendungserzeugte Komponenten an Seam
zurückgegeben werden
I
Abhängigkeiten werden also in beide Richtungen aufgelöst
I
neue Wortschöpfung: Dependency-Bijection, kurz Bijection
I
analog zu Injection: Outjection
I
die JSF-Seite zur Stammdatenverwaltung verwendet
"#{kunde.vorname}", also direkt ein Entity (@Name("kunde"))
I
dies werden wir jetzt beim Anmelden erzeugen und outjecten“
”
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
32 / 41
Die Anmeldeseite
< h:form id = " anmeldung " >
< div class = " usrFormEntry " >
< h:outputLabel for = " kundennummer " styleClass = " usrFormLabel "
Kundennummer:
</ h:outputLabel >
< h:inputText id = " kundennummer "
value = " #{ loginHandler . kundennummer } "
required = " true " styleClass = " usrFormValue " / >
</ div >
< div class = " usrFormEntry " >
< h:outputLabel for = " passwort " styleClass = " usrFormLabel " >
Passwort: </ h:outputLabel >
< h:inputSecret id = " passwort " value = " #{ loginHandler . passwort
required = " true " styleClass = " usrFormValue " / >
</ div >
< div class = " usrFormEntry " >
< h:commandButton action = " #{ loginHandler . login } "
value = " Anmelden " styleClass = " usrFormSubmit " / >
</ div >
</ h:form >
2.4 Das Anwendungsbeispiel
Analyse
I
nichts bsonderes
I
es muss alles im loginHandler geschehen
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
34 / 41
2.4 Das Anwendungsbeispiel
Die Komponente loginHandler
@Stateless
@Scope ( SESSION )
@Name ( " loginHandler " )
public class LoginHandler implements Lo ginHan dlerLo cal {
@Pers is t e nc e C o nt e x t
private EntityManager em ;
@Out
private Kunde kunde = new Kunde ();
private String kundennummer ;
private String passwort ;
...
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
35 / 41
2.4 Das Anwendungsbeispiel
Analyse
I
Stateless Session-Bean
I
bekommt vom Container den Entity-Manager injiziert (ist EJB 3.0,
nicht Seam)
I
gibt Seam die Komponente kunde zurück (Name der Komponente ist
Variablenname)
I
kundennummer und passwort aus GUI
I
wie wird kunde erzeugt?
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
36 / 41
2.4 Das Anwendungsbeispiel
Die Komponente loginHandler II
public String login () {
Query query = em . createQuery (
" select k from Kunde k "
+ " where k . kundennummer = : kundennummer "
+ " and k . passwort = : passwort " );
List l = query . setParameter ( " kundennummer " , kundennumme
. setParameter ( " passwort " , passwort )
. getResultList ();
if ( l . size () == 1) {
kunde = ( Kunde ) l . get (0);
return " / stammdaten . xhtml " ;
} else {
FacesMessages . instance ()
. add ( " Falsche Kundennummer / Passwort - Kombination "
return null ;
}
}
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
37 / 41
2.4 Das Anwendungsbeispiel
Analyse
I
JPA-Query (einfach zu verstehen)
I
wird mit Parametern aus GUI versehen
I
return "/stammdaten.xhtml": Seam erlaubt auch direkte
Navigation ohne Navigationsregeln in faces-config.xml
I
einfaches Erzeugen von JSF-Messages
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
38 / 41
2.4 Das Anwendungsbeispiel
Die Stammdatenverwaltung
I
war einfache JSF-Seite (
I
mit direkter Verwendung von Entity-Properties
I
und mit Action-Methode speichern() in der Komponente
stammdatenHandler (nächste Seite)
stammdaten.xhtml
)
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
39 / 41
Komponente stammdatenHandler
@Stateful
@Scope ( SESSION )
@Name ( " stammd atenHa ndler " )
public class Sta mmdatenHandler
implements S t am mda te nH an dle rL oc al {
@Persis t e nc e C on t ext ( type = EXTENDED )
private EntityManager em ;
@In @Out
private Kunde kunde ;
public String speichern () {
em . merge ( kunde );
return null ;
}
@Destroy @Remove
public void destroy () {}
}
2.4 Das Anwendungsbeispiel
Analyse
I
I
@In, @Out: Bijection (beide Richtungen)
speichern()-Methode sehr einfach
I
I
I
merge() vereinigt den Zustand des Entities mit dem aktuellen
Persistenzkontext
alle Methoden laufen in Java-EE default-mäßig in einer Transaktion,
daher kein manueller Transaktions-Code
@Destroy und @Remove sind die Seam- und Java-EE-Annotationen
fürs Aufräumen“. Müssen bei zustandsbehafteter Session-Bean
”
vorhanden sein.
Max Mustermann (FBI, Uni Musterhausen) JBoss Seam Kapitel 2: Komponenten-Framework
WS 2008/09
41 / 41

Documentos relacionados