4.5 JSF mit EJB und JPA -...

293
Prof. Dr. Stephan Kleuker 310 Komponentenbasierte Software- Entwicklung 4.5 JSF mit EJB und JPA Ziel: einfache Persistierung von Daten (Create, Read, Update, Delete) mit Transaktionssteuerung DB einbinden Kurzer Überblick EJB Controller zur Seitenverwaltung Ausgabe dynamischer Tabellen

Transcript of 4.5 JSF mit EJB und JPA -...

Page 1: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

310Komponentenbasierte Software-Entwicklung

4.5 JSF mit EJB und JPA

Ziel: einfache Persistierung von Daten (Create, Read, Update, Delete) mit Transaktionssteuerung

• DB einbinden

• Kurzer Überblick EJB

• Controller zur Seitenverwaltung

• Ausgabe dynamischer Tabellen

Page 2: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

311Komponentenbasierte Software-Entwicklung

Datenbank in Server einbinden (1/2)

Einschub: Nutzung von JPA bei DB im Server

• Datenbank einrichten

• Data Source einrichten

Page 3: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

312Komponentenbasierte Software-Entwicklung

Datenbank in Server einbinden (2/2)

• Datenbank wird unter JNDI-Namen im Server registriert

• JSF-Applikation kann über JNDI auf DB zugreifen

• JSF-Container regelt DB-Zugriff (nicht Nutzer!), typische container-managed Persistance [geht auch individuell]

Page 4: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

313

Erinnerung: beans.xml

• Für die Nutzung von CDI (Contexts and DependencyInjection) wird Datei beans.xml benötigt, die sich im Ordner WEB-INF befinden muss

• Wenn nicht da, erzeugen

• vorletzte Zeile ändern (statt annotated in all)

Komponentenbasierte Software-Entwicklung

Page 5: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

314

EJB-SessionBeans

Architekturvariante

• bisher einfache direkte Software-Architektur (nutzbar für kleinere und mittlere Projekte)

• Problem: Skalierung nicht unbedingt sichergestellt, da Server nicht im Detail eingreifen kann

• Problem: direkte Nutzung von JPA wäre sehr bastelig

• Lösung: Datenbankzugriff in eigene Klasse (Enterprise JavaBean, EJB) auslagern

• EJB werden vom Server verwaltet (Tempo, Skalierung)

• EJB werden in Verwaltungsklassen injiziert

Komponentenbasierte Software-Entwicklung

Page 6: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

315

EJB - Konzept

• Standardisierte Komponenten eines JEE-Servers• Klassen zur Steuerung von Prozessen und Verwaltung von

Daten, die leicht in anderen EJB-Applikationen nutzbar sind• Unterstützt mit wenig Aufwand

– Transaktionssteuerung (Transaktion pro Methodenaufruf)– Sicherheitseinstellungen– Identifikation von Objekten zur Zusammenarbeit

• Drei Arten (local und remote Varianten)– Entity Bean (POJO, @Entity wie bereits bekannt)– Session Bean: Kommunikation mit (End-)Anwendungen

• @Stateless: bei jeder Nutzung neu erstellt• @Stateful: in einer Session nutzbar

– Message Driven Bean: asynchroner Nachrichtenablauf

Komponentenbasierte Software-Entwicklung

Page 7: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

316

Systematische Architektur

• Ansatz: mehrere Schichten, jede Schicht redet nur mit den umgebenden Schichten

• GUI konsequent vom Rest trennen, um Schicht einfach auszutauschen

• GUI kennt keine Fachklassen, nur Strings und Zahlen

• GUI erhält View-Controller (View-Model), der Zustand des GUIs kennt und Verbindung zur Geschäftslogik enthält

• Geschäftslogik hat keine Information über GUI

• Persistenz-Schicht sollte austauschbar sein

• Hier: konsequenter Einsatz von Injection

• Literatur: M. Yener, A. Theedom, Java EE Design Patterns, Wrox, John Wiley & Sons, Indianapolis (USA), 2015

Komponentenbasierte Software-Entwicklung

Page 8: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

317

Mini-Beispiel (1/9)

• Nicht editierbare Aufgabenliste

Komponentenbasierte Software-Entwicklung

Page 9: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

318

Mini-Beispiel (2/9): Architektur

Komponentenbasierte Software-Entwicklung

Page 10: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

319

Mini-Beispiel (3/9): Projektaufbau

Komponentenbasierte Software-Entwicklung

Page 11: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

320

Mini-Beispiel (4/9): Datenmodell@Entity

public class Aufgabe implements Serializable{

@Id @GeneratedValue(strategy = GenerationType.AUTO)

private int id;

private String aufgabe;

public int getId() { return id; }

public void setId(int id) {

this.id = id;

}

public String getAufgabe() { return aufgabe;}

public void setAufgabe(String aufgabe) {

this.aufgabe = aufgabe;

}

}

Komponentenbasierte Software-Entwicklung

Page 12: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

321

Mini-Beispiel (5/9): Persistenzschicht (1/2)

public class MyProducers {

@Produces // evtl. mit Qualifier kennzeichnen

@PersistenceContext(unitName = "ListeJSFEJBPU")

private EntityManager em;

}

• Injection passiert mit CDI (Contexts and Dependency Injection, später mehr)

• CDI und EJB getrennte Konzepte

• so werden EJBs dem CDI-Lebenszyklus untergeordnet

• @Produces: angelegtes Objekt über CDI injizierbar

• Muss! bei vorgeschlagener Architektur

• gibt Alternativen zu EJB über Annotationen

Komponentenbasierte Software-Entwicklung

Page 13: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

322

Mini-Beispiel (6/9): Persistenzschicht (2/2)@Stateless

public class Persistence {

@Inject

private EntityManager em;

public void persist(Object object) {

em.persist(object); //Exception weiterreichen

}

public Object merge(Object object) {

return em.merge(object); //Exception weiterreichen

}

public List<Aufgabe> findAllAufgaben() {

return em.createQuery("SELECT a FROM Aufgabe a", Aufgabe.class)

.getResultList();

}

}Komponentenbasierte Software-Entwicklung

Page 14: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

323

Mini-Beispiel (7/9): Geschäftslogik@Dependent // hier wären fachliche Berechnungen

public class Modell implements Serializable{

@Inject

private Persistence db;

public List<String> aufgaben(){ // könnte auch Aufgaben liefern

List<String> erg = new ArrayList<>();

for(Aufgabe a:this.db.findAllAufgaben()){

erg.add(a.getAufgabe());

}

return erg;

}

public void aufgabeHinzu(String aufgabe){

Aufgabe a = new Aufgabe();

a.setAufgabe(aufgabe);

this.db.persist(a);

}

}Komponentenbasierte Software-Entwicklung

Page 15: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

324

Mini-Beispiel (8/9): ViewModel@Named(value = "vm")

@RequestScoped

public class ViewModel implements Serializable{

private String aufgabe;

@Inject

private Modell model;

public List<String> aufgaben(){

System.out.println("aufgaben");

return this.model.aufgaben();

}

public void aufgabeHinzu(){

this.model.aufgabeHinzu(this.aufgabe);

this.aufgabe = "";

}

public String getAufgabe() { return aufgabe; }

public void setAufgabe(String aufgabe) {

this.aufgabe = aufgabe;

}

}

Komponentenbasierte Software-Entwicklung

Page 16: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

325

Mini-Beispiel (9/9): View

<h:head>

<title>Aufgaben</title>

</h:head>

<h:body>

<h:form id ="form">

<h:outputText value="Aufgabe: "/>

<h:inputText id="aufgabe" value="#{vm.aufgabe}"/>

<h:commandButton id="hinzu" value="OK"

action="#{vm.aufgabeHinzu()}"/>

<br/>

<ui:repeat value="#{vm.aufgaben()}" var="a">

#{a} <br/>

</ui:repeat>

</h:form>

</h:body>

</html>

Komponentenbasierte Software-Entwicklung

Page 17: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

326

@Dependent

@Dependent

public class Modell implements Serializable{ … }

• Annotation gehört zu CDI (später)

• Injiziertes Objekt übernimmt Scope des nutzenden Objekts

• es werden dann ausschließlich Objekte dieser Klasse vom CDI-Framework erzeugt; nie selbst den Konstruktor aufgerufen

… // in anderer Klasse@Inject

private Modell model;

Komponentenbasierte Software-Entwicklung

Page 18: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

327

Angedeutetes Problem (1/3): Ausgaben

• man erkennt, dass aufgaben() sehr häufig aufgerufen wird

• Problem, da jedes Mal Datenbank genutzt wird

Komponentenbasierte Software-Entwicklung

Ausgaben nach letzter Eingabe

Information: aufgaben

Information: aufgaben

Information: aufgaben

Information: aufgaben

Information: aufgaben

Information: aufgaben

Page 19: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

328

Angedeutetes Problem (2/3): Lösung

public class ViewModel implements Serializable{

private String aufgabe;

// neu: lokale Variable fuer darzustellende Objekte

// hier sehr verinfacht nur Strings

private List<String> aufgaben; // neu

@Inject

private Modell model;

// neu: nach Objekterzeugung (und Injects)

@PostConstruct

public void init(){

this.aufgaben = this.model.aufgaben();

}

public List<String> aufgaben(){

return this.aufgaben; // neu

// return this.model.aufgaben();

}

Komponentenbasierte Software-Entwicklung

Page 20: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

329

Angedeutetes Problem (3/3): Lösung

• letzte Folie zeigt Lösung mit lokaler Datenhaltung der anzuzeigenden Daten

• JSF-Framework fragt darzustellende Daten mehrfach ab

• bei SessionScope

– rufe nach eigener Änderung (CREATE, UPDATE, DELETE) die darzustellenden Daten erneut ab

– Erinnerung: Session-kontext wird gespeichert und bei nächster Seitennutzung wieder hergestellt

– mit @PostConstruct annotierte Methode kann auch an anderen Stellen aufgerufen werden

Komponentenbasierte Software-Entwicklung

Page 21: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

330

4.6 Detaillierteres Beispiel: Mitarbeiterverwaltung

• Zu entwickeln ist eine Komponente zur Verwaltung von Mitarbeitern

• generelle Attribute: Mitarbeiternummer (minr), Vorname, Nachname, Gehalt, Geburtsdatum

• Beispiel zeigt Varianten bei der Umsetzung; ob sinnvoll hängt von individuellem Projekt ab

• Besonderheit: zu entwickelnde Komponente darf nur Teile der Attribute füllen (aus juristischen oder … Gründen, erfolgt die Vervollständigung der Daten mit Gehalt und Geburtsdatum in einer anderen Komponente)

Komponentenbasierte Software-Entwicklung

Page 22: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

331

Ergebnis

Komponentenbasierte Software-Entwicklung

Page 23: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

332

Beispiel: Klasse Mitarbeiter

@Entity

public class Mitarbeiter implements Serializable{

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private int minr;

private String vorname;

private String nachname;

private int gehalt;

@Temporal(javax.persistence.TemporalType.DATE)

private Date geburtsdatum;

@Version

private int version;

public Mitarbeiter(){}

// weitere Konstruktoren denkbar

// getter und setter; equals(), HashCode() basierend auf minr

Komponentenbasierte Software-Entwicklung

Page 24: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

333

Erinnerung: MitarbeiterBuilder (1/2)public class MitarbeiterBuilder implements Serializable{

private int minr;

private String vorname;

private String nachname;

private int gehalt;

private Date geburtsdatum;

private MitarbeiterBuilder(){};

public static MitarbeiterBuilder create(){

return new MitarbeiterBuilder();

}

public MitarbeiterBuilder minr(int minr){

this.minr = minr;

return this;

} // analog fuer vorname und nachname

Komponentenbasierte Software-Entwicklung

Page 25: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

334

Erinnerung: MitarbeiterBuilder (2/2)public MitarbeiterBuilder gehalt(int gehalt){

this.gehalt = gehalt;

return this;

}

public MitarbeiterBuilder geburtsdatum(Date geburtsdatum){

this.geburtsdatum = geburtsdatum;

return this;

}

public Mitarbeiter build(){

Mitarbeiter ergebnis = new Mitarbeiter();

ergebnis.setVorname(this.vorname);

ergebnis.setNachname(this.nachname);

ergebnis.setGehalt(this.gehalt);

ergebnis.setGeburtsdatum(this.geburtsdatum);

return ergebnis;

}

}Komponentenbasierte Software-Entwicklung

Page 26: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

335

Informationsweitergabe zwischen Schichten (1/3)

• Alle Schichten nutzen Objekte aus der Datenbank

• einfach realisierbar

• wenn nur Teilinformationen benötigt ist es langsam, speicheraufwändig; soll jeder DB-Objekte kennen?

Komponentenbasierte Software-Entwicklung

Oberfläche

Oberflächensteuerung

Persistenz

Geschäftslogik

Datenbank<<Entity>>

<<nutzt>>

Page 27: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

336

Informationsweitergabe zwischen Schichten (2/3)

• Informationen werden in Data-Transfer-Objekte (DTO) verpackt

• Information können passenden Typ haben, in DTO validieren

• DTO auch Value Object genannt

• einmalig einpacken (marshalling) und dann auspacken (unmarshalling) von Informationen

Komponentenbasierte Software-Entwicklung

Oberfläche

Oberflächensteuerung

Persistenz

Geschäftslogik

Datenbank

<<DTOs>>

<<nutzt>>

<<erzeugt>>

Page 28: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

337

Informationsweitergabe zwischen Schichten (3/3)

• DTO pro Kommunikation von Schichten

• Information genau an nutzende Schicht angepasst, z. B. Oberfläche benötigt nur elementare Datentypen

• seht häufiges einpacken und auspackenKomponentenbasierte Software-

Entwicklung

Oberfläche

Oberflächensteuerung

Persistenz

Geschäftslogik

Datenbank

<<DTOgp>><<nutzt>>

<<erzeugt>>

<<DTOog>><<nutzt>>

<<erzeugt>>

<<DTOoo>><<nutzt>>

<<erzeugt>>

Page 29: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

338

Data Transfer Object (1/4)

public class MitarbeiterDTO implements Serializable{

private int minr; // gehalt soll nicht sichtbar sein

private String vorname;

private String nachname;

private String alter; // fuer Ausgabe vorbereitet

private String befehl; // fuer Steuerung

public MitarbeiterDTO(){ }

public MitarbeiterDTO(int minr, String vorname

, String nachname, String alter, String befehl) {

this.minr = minr;

this.vorname = vorname;

this.nachname = nachname;

this.alter = alter;

this.befehl = befehl;

}

Komponentenbasierte Software-Entwicklung

Page 30: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

339

Data Transfer Object (2/4)

public static MitarbeiterDTO toMitarbeiterDTO(Mitarbeiter m){

if (m == null){

return null;

}

LocalDate jetzt = LocalDate.now();

Date tmp = m.getGeburtsdatum();

String alter = "unbekannt";

if (tmp != null){

LocalDate geburt = tmp.toInstant()

.atZone(ZoneId.systemDefault()).toLocalDate();

alter = "" + ChronoUnit.YEARS.between(geburt, jetzt);

}

return new MitarbeiterDTO(m.getMinr(), m.getVorname()

, m.getNachname(), alter,"");

}

Komponentenbasierte Software-Entwicklung

Page 31: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

340

Data Transfer Object (3/4)public Mitarbeiter toMitarbeiter(){

return MitarbeiterBuilder

.create() .minr(this.minr) .vorname(this.vorname)

.nachname(this.nachname).build();

}

public void aktualisieren(Mitarbeiter m){

m.setVorname(this.vorname);

m.setNachname(this.nachname);

}

public String validieren(){

String ergebnis = "";

if(this.vorname.trim().length() < 2

|| this.nachname.trim().length() <2){

ergebnis = "Vor- und Nachname müssen mind. zwei Zeichen";

}

return ergebnis;

}Komponentenbasierte Software-Entwicklung

Projekt benötigt ein Konzept zum Umgang mit Validierungen (nur eine pro Client und Server)

Codierung: leerer String ok, sonst Fehlermeldung (schöner

mit eigener Klasse)

Page 32: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

341

Data Transfer Object (4/4)@Override

public int hashCode() {

int hash = 5;

hash = 53 * hash + this.minr;

return hash;

}

@Override

public boolean equals(Object obj) {

if (this == obj) {

return true;

}

if (obj == null || this.getClass() != obj.getClass()) {

return false;

}

return this.minr != ((MitarbeiterDTO) obj).minr;

}

// getter und setter für: minr, vorname, nachname, alter

Komponentenbasierte Software-Entwicklung

hashCode und equals basieren nur auf minr

Page 33: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

342

Architektur

Komponentenbasierte Software-Entwicklung

Page 34: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

343

Persistenz

• Persistenz wie im ersten Beispiel behandelt

• hier könnten u. a. Transaktionen scheitern -> Methoden werden Exception

• sind RuntimeExceptions, kein throws oder catch benötigt

• benötigt wird einheitliches Konzept, wie mit Exceptions umgegangen werden soll; hier direkte Weitergabe und Behandlung auf Controller-Ebene

• Hinweis: diese Exceptions sind ineinander geschachtelt, so dass Grund schwer feststellbar: e. getCausedByException()

• EJBException, RollbackException, PersistenceException, SQLIntegrityConstraintViolationException, …

Komponentenbasierte Software-Entwicklung

Page 35: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

344

Persistenz (1/3)

public class EJBinCDIIntegration {

@Produces

@PersistenceContext(unitName = "kbseMitarbeiterverwaltungPU")

private EntityManager em;

}

• Erinnerung: EJB wird CDI untergeordnet (bei Stateless recht einfach machbar)

Komponentenbasierte Software-Entwicklung

Page 36: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

345

Persistenz (2/3)

@Stateless

public class Persistence {

@Inject

private EntityManager em;

public void save(MitarbeiterDTO m) {

this.em.persist(m.toMitarbeiter());

}

public void update(MitarbeiterDTO m) {

Mitarbeiter mit = this.em.find(Mitarbeiter.class, m.getMinr());

m.aktualisieren(mit);

this.em.persist(mit);

}

public MitarbeiterDTO mitarbeiter(int minr) {

return MitarbeiterDTO

.toMitarbeiterDTO(this.em.find(Mitarbeiter.class, minr));

}

Komponentenbasierte Software-Entwicklung

Page 37: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

346

Persistenz (3/3)

public void delete(MitarbeiterDTO m) {

Mitarbeiter mit = this.em.find(Mitarbeiter.class, m.getMinr());

this.em.remove(mit);

}

public List<MitarbeiterDTO> alleMitarbeiter() {

List<Mitarbeiter> tmp = this.em

.createQuery("SELECT m FROM Mitarbeiter m",Mitarbeiter.class)

.getResultList();

List<MitarbeiterDTO> ergebnis = new ArrayList<>();

tmp.forEach(m ->

ergebnis.add(MitarbeiterDTO.toMitarbeiterDTO(m)));

return ergebnis;

}

}

Komponentenbasierte Software-Entwicklung

TODO: als @NamedQueryauslagern

Page 38: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

347

Controller

• auf dieser Ebene gibt es die Klassen zur Verwaltung der Entitäten

• diese Klasse sollte nichts/wenig über die Oberfläche, generell über ihre Nutzer, wissen

• Klasse kann völlig unabhängig von JSF (aber auch JPA) gestaltet werden (würde sich Interface anbieten)

• um unabhängig von JSF zu sein, gibt es neutrale Klasse Resultat, die informiert, ob ein Aktion erfolgreich war und beim Scheitern einen Grund angeben kann [oftmals ist genauerGrund für Endnutzer uninteressant]

Komponentenbasierte Software-Entwicklung

Page 39: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

348

Resultatpublic class Resultat implements Serializable{

private boolean ergebnis = true;

private String kommentar ="";

public Resultat(){}

public Resultat(boolean ergebnis, String kommentar) {

this.ergebnis = ergebnis;

this.kommentar = kommentar;

}

public boolean isErgebnis() { return ergebnis;}

public void setErgebnis(boolean ergebnis) {

this.ergebnis = ergebnis;

}

public String getKommentar() { return kommentar; }

public void setKommentar(String kommentar) {

this.kommentar = kommentar;

}Komponentenbasierte Software-

Entwicklung

in POJOs bei boolean ist isstatt get erlaubt

Page 40: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

349

Controller (1/4)@Dependent

public class Controller implements Serializable {

@Inject

private Persistence persist;

public Resultat save(MitarbeiterDTO m) {

String ergebnis = m.validieren();

if (!ergebnis.equals("")) {

return new Resultat(false, ergebnis);

}

try {

this.persist.save(m);

return new Resultat(true, "erfolgreich gespeichert");

} catch (Throwable e) { // egal was, immer fangen

return new Resultat(false

,"Aktion gescheitert: " + e.getMessage());

}

}Komponentenbasierte Software-Entwicklung

Page 41: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

350

Controller (2/4)

public List<MitarbeiterDTO> alleMitarbeiter() {

return this.persist.alleMitarbeiter();

}

public Resultat update(MitarbeiterDTO m) {

String ergebnis = m.validieren();

if (!ergebnis.equals("")) {

return new Resultat(false, ergebnis);

}

try {

this.persist.update(m);

return new Resultat(true, "erfolgreich aktualisiert");

} catch (Throwable e) {

return new Resultat(false,"Aktion gescheitert: "

+ "Mitarbeiter gelöscht? Detail: " + e.getMessage());

}

}

Komponentenbasierte Software-Entwicklung

Page 42: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

351

Controller (3/4)public Resultat delete(MitarbeiterDTO m) {

String ergebnis ="";

try {

this.persist.delete(m);

return new Resultat(true, "erfolgreich gelöscht");

} catch (Throwable e) {

try {

if (this.mitarbeiter(m.getMinr()) != null) {

ergebnis = " löschen gescheitert " + e;

}

else {

ergebnis = "erfolgreich gelöscht (war vorher schon)";

}

} catch(Exception e2) {

ergebnis = "Aktion gescheitert: " + e2;

}

return new Resultat(false, ergebnis);

}

}

Komponentenbasierte Software-Entwicklung

Page 43: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

352

Controller (4/4)public MitarbeiterDTO mitarbeiter(int minr) {

return this.persist.mitarbeiter(minr);

}

}

Komponentenbasierte Software-Entwicklung

Page 44: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

353

ViewModel

• erst ab hier JSF-spezifisch

• hier kann Aufteilung in ViewModelController (z. B. SessionScoped) und ViewModel (RequestScoped) sinnvoll sein

• leider fliegen in der Literatur die Namen für diese Modellebene oft durcheinander; teilweise aus „politischen“ Überlegungen, da MVVM nach Microsoft und birektionalemBinding klingt

• ViewModel enthält spezielle Daten, um Oberfläche zu steuern (hier welcher Bearbeitungsmodus)

• hier neu: JSF unterstützt auch klassische HTTP-get-Aufrufe mit Parametern [keine Architekturbesonderheit]

Komponentenbasierte Software-Entwicklung

Page 45: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

354

ViewModel (1/4)

@Named("mvm")

@RequestScoped

public class MitarbeiterViewModel implements Serializable {

private MitarbeiterDTO mitarbeiter; // zur Bearbeitung

private List<MitarbeiterDTO> alle;

private String ausgabe = ""; //Verzicht auf FacesContext

private boolean editmodus;

private boolean loeschenmodus;

@Inject

private Controller controller;

public MitarbeiterViewModel() {

}

Komponentenbasierte Software-Entwicklung

Page 46: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

355

ViewModel (2/4)@PostConstruct

public void initialisieren() {

this.alle = this.controller.alleMitarbeiter();

this.mitarbeiter = new MitarbeiterDTO();

this.editmodus = false;

this.loeschenmodus = false;

}

public void uebernehmen() {

if (this.editmodus) {

this.ausgabe = this.controller

.update(this.mitarbeiter).getKommentar();

} else {

this.ausgabe = this.controller

.save(this.mitarbeiter).getKommentar();

}

this.initialisieren();

}

Komponentenbasierte Software-Entwicklung

Page 47: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

356

ViewModel (3/4)

public void aufrufVerarbeiten() { // nachdem Parameter gelesen

if (this.editmodus) {

this.mitarbeiter = this.controller

.mitarbeiter(this.mitarbeiter.getMinr());

if (this.mitarbeiter != null) {

return;

} else {

this.editmodus = false;

this.ausgabe = "Mitarbeiter existiert nicht (mehr)";

}

}

Komponentenbasierte Software-Entwicklung

Page 48: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

357

ViewModel (4/4)

if (this.loeschenmodus) {

this.mitarbeiter = this.controller

.mitarbeiter(this.mitarbeiter.getMinr());

if (this.mitarbeiter != null) {

this.ausgabe = this.controller

.delete(this.mitarbeiter).getKommentar();

this.initialisieren();

} else {

this.loeschenmodus = false;

this.ausgabe = " Mitarbeiter geloescht (vorher schon)";

}

}

this.mitarbeiter = new MitarbeiterDTO();

}

Komponentenbasierte Software-Entwicklung

Page 49: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

358

JSF-View

• hier neu: Nutzung von get-Parametern

• aktuelle Seiten nicht für Bookmarks oder Mails geeignet

• sinnvoll wäre GET-Nutzung (ab JSF 2.0 möglich, wird erweitert, mindestens 2.2.6 von mojarra notwendig)

• Ansatz: In Seite können GET-Parameter spezifiziert werden

• aufgerufene Seite erhält Parameter und kann diese in speziellen f:metadata-Tag lesen und mit Variablen des Controllers verknüpfen

• Steuerung passiert durch neue Elemente, h:button und h:link ersetzen h:commandButton und h:commandLink

• http://localhost:8080/kbseMitarbeiterverwaltung/faces/index.xhtml;jsessionid=4d39f162427f80bd9370f6db120f?minr=1552&edit=true

Komponentenbasierte Software-Entwicklung

Page 50: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

359

Konzept von get

<h:button value="Editieren" outcome="mitarbeiterParam">

<f:param name="mid" value="#{m.id}" />

<f:param name="actionId" value="2" />

</h:button>

• outcome nennt aufzurufende Seite

• Parameter per GET übergeben

• aufgerufene Seite, in <f:metadata>

– Einlesen mit<f:viewParam name="mid" value="#{controller.id}" />

– zentrale Aktion, die nach dem Einlesen passieren soll <f:viewAction action="#{controller.reagiereAufGet}"/>

Komponentenbasierte Software-Entwicklung

Page 51: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

360

View (1/6)

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html"

xmlns:f="http://xmlns.jcp.org/jsf/core">

<f:metadata>

<f:viewParam name="minr" required="false"

value="#{mvm.mitarbeiter.minr}"/>

<f:viewParam name="edit" required="false"

value="#{mvm.editmodus}"/>

<f:viewParam name="loeschen" required="false"

value="#{mvm.loeschenmodus}"/>

<f:viewAction action="#{mvm.aufrufVerarbeiten()}"/>

</f:metadata>

Komponentenbasierte Software-Entwicklung

Page 52: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

361

View (2/6)<h:head>

<title>Mitarbeiterverwaltung</title>

</h:head>

<h:body>

<h:form id="mitarbeiter">

<h:panelGrid id ="eingabe" columns="3" >

<h:outputText value="Mitarbeiternummer: "/>

<h:outputText value="#{mvm.mitarbeiter.minr}"

rendered="#{mvm.mitarbeiter.minr != 0}"/>

<h:outputText value="vom System vergeben"

rendered="#{mvm.mitarbeiter.minr == 0}"/>

<br/>

<h:outputText value="Vorname: "/>

<h:inputText id="vorname"

value="#{mvm.mitarbeiter.vorname}"/>

<h:message for="vorname" style="color:red"/>

Komponentenbasierte Software-Entwicklung

Page 53: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

362

View (3/6)

<h:outputText value="Nachname: "/>

<h:inputText id="nachname"

value="#{mvm.mitarbeiter.nachname}"/>

<h:message for="nachname" style="color:red"/>

<h:commandButton value="übernehmen"

action="#{mvm.uebernehmen}"/>

<h:button value="abbrechen"

outcome="index"

rendered="#{mvm.editmodus}">

<f:param name="edit" value="false" />

</h:button>

</h:panelGrid>

<h:outputText value="#{mvm.ausgabe}"/>

<br/>

Komponentenbasierte Software-Entwicklung

nur im Edit-Modus diesen Knopf einblenden

rufe outcome-Seite mit diesem get-Parameter auf:

index.xhtml?edit=false

Page 54: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

363

View (4/6)

<h:panelGrid rendered="#{!empty mvm.alle}">

<h:dataTable value="#{mvm.alle}" var="m" border="0" >

<h:column>

<f:facet name="header">

<h:outputText value="Minr" />

</f:facet>

<h:outputLabel value="#{m.minr}"/>

</h:column>

<h:column>

<f:facet name="header">

<h:outputText value="Vorname" />

</f:facet>

<h:outputLabel value="#{m.vorname}"/>

</h:column>

Komponentenbasierte Software-Entwicklung

Page 55: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

364

View (5/6)<h:column>

<f:facet name="header">

<h:outputText value="Nachname" />

</f:facet>

<h:outputLabel value="#{m.nachname}"/>

</h:column>

<h:column>

<f:facet name="header">

<h:outputText value="Alter" />

</f:facet>

<h:outputLabel value="#{m.alter}"/>

</h:column>

Komponentenbasierte Software-Entwicklung

Page 56: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

365

View (6/6)

<h:column>

<h:button value="editieren" outcome="index">

<f:param name="minr" value="#{m.minr}" />

<f:param name="edit" value="true" />

</h:button>

</h:column>

<h:column>

<h:button value="löschen" outcome="index">

<f:param name="minr" value="#{m.minr}" />

<f:param name="loeschen" value="true" />

</h:button>

</h:column>

</h:dataTable>

</h:panelGrid>

</h:form>

</h:body>

</html>

Komponentenbasierte Software-Entwicklung

Page 57: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

366

4.7 Testen von JEE-Programmen

Erinnerung an Testarten

• Unit-Tests: durch Entwickler, Methoden einzelner Klassen, Zusammenspiel zusammengehöriger Klassen

• Komponententests: Test von ein oder mehr Packages, Fokus auf die dazwischenliegenden Schnittstellen

• Systemtests, Abnahmetests: Tests des Gesamtsystems als Blackbox, Fokus auf zentrale Use Cases, Endabnahme

• technisches Problem: JUnit kann nicht direkt @Inject(allgemein CDI) nutzen, bzw. Objekte zur Verfügung stellen

• Ergänzung von JUnit durch Arquillian, http://arquillian.org/

• Installation und Start kann sehr ätzend sein, danach absolut intuitiv nutzbar

Komponentenbasierte Software-Entwicklung

Page 58: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

367

Gutes Testen

• generell muss Software testbar geschrieben werden (get-, set-Methoden, kurze Methoden mit wenig Verzweigungen, …)

• Testentwickler muss erfahrener Software-Entwickler sein

– kennt die typischen Fallen in einer Software

– muss eine sinnvolle Testarchitektur (wart- und erweiterbar) entwickeln

• Testentwickler muss typische Use Cases der SW kennen

• Ziel: kleine Änderungen in der zu testenden Software (SuT = System under Test) führt nur zu kleinen Änderungen in Tests

• Tests so entwickeln, dass Entwickler der SuT weiterentwickelt, diesen Tests trauen kann (keine Abhängigkeiten von der Zeit)

• Ziel: Testautomatisierung, Continous Integration / Development

Komponentenbasierte Software-Entwicklung

Page 59: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

368

Arquillian

• unterstützt CDI, dadurch @Inject in Tests nutzbar

• benötigt Server auf dem zu testende App installiert wird, hierzu gibt es folgende Varianten:

– embedded Container: basiert auf GlassFish; erlaubt normales Deployment, kann unabhängig vom realen System konfiguriert werden; nutzt gleiche JVM wie Tests; ist nah (aber nicht gleich) dem Zielsystem

– managed Container: läuft auf Ziel-Server; Arquillian muss sich damit verbinden (-> z. B. für Komponententests)

• hier: embedded Container, realen Server zum Testen stoppen, DB muss laufen

• Tests auch ohne Arquillian möglich, dazu von Hand set-Injection nutzen, Mocks erstellen, (Workarounds basteln)

Komponentenbasierte Software-Entwicklung

Page 60: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

369

Arquillian - Start

• unsere Web-Applikationen bestehen aus WebArchive (war-Datei, gepackt), die festen Aufbau hat und u. a. jar-Dateien enthält

• nur war-Datei benötigt, wenn alle benutzten Bibliotheken im Server vorhanden (zentrales lib-Verzeichnis)

• Arquillian unterstützt den Bau solcher WebArchives für Applikationen (Shrinkwrap)

• wir nutzen gleiche Version des embedded GlassFish und des realen Servers (-> war-Datei kann direkt genutzt werden)

• folgende Folien zeigen nur Beispiele, die systematische aufbereitet werden müssten (z. B. Hilfsmethoden auslagern)

• Literatur: J. D. Ament, Arquillian Testing Guide, Packt Publishing, Birmingham, UK, 2013

Komponentenbasierte Software-Entwicklung

Page 61: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

370

Arquillian – Beispielnutzung (1/7)

@RunWith(Arquillian.class)

public class PersistenceTest {

@Inject

Persistence persist;

MitarbeiterDTO zuLoeschen;

@After

public void after(){

if (this.zuLoeschen != null){

this.persist.delete(this.zuLoeschen);

this.zuLoeschen = null;

}

}

Komponentenbasierte Software-Entwicklung

Page 62: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

371

Arquillian – Beispielnutzung (2/7)

@Deployment

public static WebArchive createDeployment() {

WebArchive war = ShrinkWrap.createFromZipFile(

WebArchive.class

, new File("dist/kbseMitarbeiterverwaltung.war"));

System.out.println("war: " + war + " " + war.getContent());

return war;

}

Ausgabe: war: kbseMitarbeiterverwaltung.war: 17 assets

{BasicPath [context=/META-INF]=/META-INF, BasicPath

[context=/META-INF/MANIFEST.MF]=/META-INF/MANIFEST.MF,

BasicPath [context=/WEB-INF]=/WEB-INF, BasicPath

[context=/WEB-INF/classes]=/WEB-INF/classes, BasicPath

[context=/WEB-INF/classes/META-INF]=/WEB-INF/classes/META-

INF, BasicPath [context=/WEB-INF/classes/access]=/WEB-

INF/classes/access, BasicPath [context=/WEB-

INF/classes/controller]=/WEB-INF/classes/controller, Komponentenbasierte Software-

Entwicklung

Page 63: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

372

Arquillian – Beispielnutzung (3/7)@Test

public void ejbBeispielTest() {

List<MitarbeiterDTO> alt = this.persist.alleMitarbeiter();

String name = new Date().toString();

// minr wird ignoriert, da sie von JPA generiert wird

MitarbeiterDTO mi = new MitarbeiterDTO(42, name + "1"

, name + "2", "42", "");

this.persist.save(mi);

List<MitarbeiterDTO> neu = this.persist.alleMitarbeiter();

neu.removeAll(alt); // geht nur mit passendem equals

Assert.assertEquals("ein neues Objekt", 1, neu.size());

this.zuLoeschen = neu.get(0);

Assert.assertEquals("falscher Vorname"

, name + "1", neu.get(0).getVorname());

Assert.assertEquals("falscher Nachname"

, name + "2", neu.get(0).getNachname());

}

Komponentenbasierte Software-Entwicklung

Page 64: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

373

Arquillian – Beispielnutzung (4/7) - Hilfsmethode

// Idee von letzter Folie auslagern (gibt noch sicherere Wege

// nicht existierende Daten zu erzeugen)

public MitarbeiterDTO neuerMitarbeiter(){

List<MitarbeiterDTO> alt = this.persist.alleMitarbeiter();

String name = new Date().toString();

// minr wird ignoriert, da sie von JPA generiert wird

MitarbeiterDTO mi = new MitarbeiterDTO(42, name + "1"

, name + "2", "42", "");

this.persist.save(mi);

List<MitarbeiterDTO> neu = this.persist.alleMitarbeiter();

neu.removeAll(alt);

return neu.get(0);

}

// weitere Erkenntnis: wuerde persist zumindest die erzeugte

// minr zurueckliefern, waere Testerstellung einfacher

Komponentenbasierte Software-Entwicklung

Page 65: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

374

Arquillian – Beispielnutzung (5/7) – mehrere Nutzer@Inject

Persistence pers2;

@Test

public void testVerschiedenePersistenceObjekte(){

Assert.assertNotEquals(this.pers2, this.persist);

}

@Test

public void testZweiterLoeschtObjektDasErsterDannAktualisiert(){

MitarbeiterDTO mi = this.neuerMitarbeiter();

this.pers2.delete(mi);

try{

this.persist.update(mi);

Assert.fail("geloeschtes Element aktualisiert");

} catch (EJBException e){

}

}

Komponentenbasierte Software-Entwicklung

Page 66: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

375

Arquillian – Beispielnutzung (6/7)@Inject

Controller control;

@Test

public void testbeispielControllernutzung(){

List<MitarbeiterDTO> alt = this.control.alleMitarbeiter();

String name = new Date().toString();

MitarbeiterDTO mi = new MitarbeiterDTO(42, name + "1"

, name + "2", "42", "");

Resultat res = this.control.save(mi);

Assert.assertTrue(mi + " nicht persistiert",res.isErgebnis());

List<MitarbeiterDTO> neu = this.control.alleMitarbeiter();

neu.removeAll(alt);

Assert.assertEquals("ein neues Objekt", 1, neu.size());

this.zuLoeschen = neu.get(0);

Assert.assertEquals(name + "1", neu.get(0).getVorname());

Assert.assertEquals(name + "2", neu.get(0).getNachname());

}

Komponentenbasierte Software-Entwicklung

Page 67: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

376

Arquillian – Beispielnutzung (7/7)@Inject

MitarbeiterViewModel mv;

@Test

public void testbeispielViewnutzung(){

List<MitarbeiterDTO> alt = this.mv.getAlle();

String name = new Date().toString();

// minr wird ignoriert, da sie von JPA generiert wird

MitarbeiterDTO mi = new MitarbeiterDTO(42, name + "1"

, name + "2", "42", "");

this.mv.setMitarbeiter(mi); // wuerde der View fuellen

this.mv.uebernehmen();

List<MitarbeiterDTO> neu = this.mv.getAlle();

neu.removeAll(alt);

Assert.assertEquals("ein neues Objekt", 1, neu.size());

this.zuLoeschen = neu.get(0);

Assert.assertEquals(name + "1", neu.get(0).getVorname());

Assert.assertEquals(name + "2", neu.get(0).getNachname());

}Komponentenbasierte Software-

Entwicklung

Page 68: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

377

Anmerkung

• Generell wird mit jedem @Inject neues Objekt erzeugt

• Ausnahme bei der Sessionsteuerung

• über arquillian.xml konfigurierbar (außerhalb des Scopes dieser Einführungsveranstaltung)

• folgender Test scheitert deshalb:@Inject

MitarbeiterViewModel mv2;

@Test

public void testVerschiedeneViewModelObjekte(){

Assert.assertNotEquals(this.mv, this.mv2);

}

Komponentenbasierte Software-Entwicklung

Page 69: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

378

Überdeckungsmessung (1/2)

Komponentenbasierte Software-Entwicklung

Page 70: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

379

Überdeckungsmessung (2/2)

Komponentenbasierte Software-Entwicklung

Page 71: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

380

Abschlussbeispiel: Traue keinen Überdeckungen

public int max(int x,

int y,

int z){

int max = 0;

if (x>z)

max = x;

if (y>x)

max = y;

if (z>y)

max = z;

return max;

}

0

1

2

3

int max = 0

if (x>z)

max = x

return max

4

5

6

7

max = y

max = z

if (y>x)

if (z>y)

• Erinnerung: Suche Maximum von drei ganzen Zahlen

Komponentenbasierte Software-Entwicklung

Page 72: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

381

Anweisungsüberdeckung - jeder Knoten einmal

0

1

2

3

max = 0

if (x>z)

max = x

return

max

4

5

6

7

max = y

max = z

if (y>x)

if (z>y)

5 4

7 5

4 7

5

7

0

1

2

3

max = 0

if (x>z)

max = x

return

max

4

5

6

7

max = y

max = z

if (y>x)

if (z>y)

4 7

5 4

7 5

5

7

7 = max (5, 7, 4)

7

7 = max (4, 5, 7)

7

Komponentenbasierte Software-Entwicklung

Page 73: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

382

Zweigüberdeckung - jede Kante einmal

0

1

2

3

max = 0

if (x>z)

max = x

return

max

4

5

6

7

max = y

max = z

if (y>x)

if (z>y)

7 4

5 7

4 5

7

7

0

1

2

3

max = 0

if (x>z)

max = x

return

max

4

5

6

7

max = y

max = z

if (y>x)

if (z>y)

5 4

7 5

4 7

5

7

0

1

2

3

max = 0

if (x>z)

max = x

return

max

4

5

6

7

max = y

max = z

if (y>x)

if (z>y)

4 7

5 4

7 5

5

7

7 = max (7, 5, 4) 7 = max (5, 7, 4)

7

7 = max (4, 5, 7)

7

Komponentenbasierte Software-Entwicklung

Page 74: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

383

Fehler kann gefunden werden

• Kenntnisse über Äquivalenzklassen !

x>y=z y=z>x y>x=z x=z>y z>y=x y=x>z

z>y>x z>x>y y>z>x y>x>z x>z>y x>y>z x=y=z

• Kenntnisse über Datenflussanalyse finden Fehler!

• benötigt große Programmiererfahrung

• benötigt sehr strukturiertes Denken

• benötigt Forderung nach intensiven Tests (auch DO-178B)

• benötigt Werkzeuge zur Automatisierung

• benötigt Zeit und Geld

• benötigt Management mit Software-Verstand

Komponentenbasierte Software-Entwicklung

Page 75: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

384

Fazit: Äquivalenzklassen und Überdeckungen

• letztes Beispiel zeigt deutlich, dass man trotz systematischer Analyse Fehler übersehen kann !!!

• sinnvolles Vorgehen:

1. Testfälle aus typischen Verhalten ableiten

2. Testfälle aus Ausnahmesituationen ableiten

3. Äquivalenzklassen überlegen und kritische Fälle systematisch analysieren

4. Überdeckung messen, bei niedrigen Prozentzahlen zunächst das „warum“ ergründen, dann ggfls. Testfälle für Überdeckungen konstruieren

Nie, nie nur als zentrales Testziel 90 % - Überdeckung angeben, da dann Orientierung an Nutzerprozessen verloren geht

Komponentenbasierte Software-Entwicklung

Page 76: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

385

5. (RESTful) Web Services

• JavaScript Object Notation

• JSON-P

• Idee: Web-Services

• Idee: RESTful

• erste Services

• GET, POST

• Clients

• Response

• Path-Parameter

• Aufrufparameter

• Architektur von REST-Applikationen

• Fallstudie (GET, POST, PUT, DELETE)

• Ausblick

Komponentenbasierte Software-Entwicklung

Page 77: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

386

Ausblick auf weitere Themen

Komponentenbasierte Software-Entwicklung

Browser

Datenbank

JPA

EJBBean

Validation

Scope

JSFRESTful

WebService

Web Sockets

1

CDI

2

3

Page 78: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

387

Einstieg JSON

• JavaScript Object Notation (http://json.org/)

• textuelles Austauschformat, abgeleitet aus JavaScript{ "name": "Tony Stark",

"alter": 42,

"firma": { "name": "Stark Industries",

"ort": "New York, N.Y"

},

"freunde":["Steve Rogers", "Bruce Banner"]

}

• Sammlung von

– (Name: Wert)-Paaren

– Arrays von Werten

• Werte können wieder aus beiden Elementen bestehen

Komponentenbasierte Software-Entwicklung

Page 79: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

388

Vereinheitlichung von JSON in Java

in JEE 7 ergänzt:

• JSR 353: JavaTM API for JSON Processing (23.5.2013)

• JSR 374: JavaTM API for JSON Processing 1.1 (24.5.2017)

https://jcp.org/en/jsr/detail?id=374

• Referenzimplementierung JSON-P https://jsonp.java.net/

• in Glassfish seit 4.0 enthalten

zwei zentrale APIs

• Object Model API; sehr analog zum DOM API für XML parsing

• Streaming API; sehr analog zum StAX API

• unabhängig von Programmiersprachen nutzbar

• kompakter als XML (ähnlich gut/schlecht menschenlesbar)

Komponentenbasierte Software-Entwicklung

Page 80: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

389

Beispiel: JSON-Object lesen (1/2)

public static void main(String[] args) {

String daten =

"{ \"name\": \"Tony Stark\","

+ " \"alter\": 42,"

+ " \"firma\": { \"name\": \"Stark Industries\","

+ " \"ort\": \"New York, N.Y\""

+ "},"

+ "\"freunde\":[\"Steve Rogers\", \"Bruce Banner\", 42]"

+ "}";

JsonReader reader = Json.createReader(new StringReader(daten));

JsonObject tony = reader.readObject();

reader.close();

//Set<String> namen = tony.keySet(); // geht auch

Komponentenbasierte Software-Entwicklung

Page 81: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

390

Beispiel: JSON-Objekt lesen (2/2)

System.out.println("Name : " + tony.getString("name"));

System.out.println("Alter : " + tony.getInt("alter"));

JsonObject firma = tony.getJsonObject("firma");

System.out.println("Firmenname : " + firma.getString("name"));

System.out.println("Umsatz : " + firma.getInt("umsatz", 20));

JsonArray freunde = tony.getJsonArray("freunde");

for (JsonValue freund : freunde) {

System.out.println(freund + " * " + freund.getValueType());

}

}

Name : Tony Stark

Alter : 42

Firmenname : Stark Industries

Umsatz : 20

Steve Rogers * STRING

Bruce Banner * STRING

42 * NUMBER

Default, wenn nicht da

Komponentenbasierte Software-Entwicklung

Page 82: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

391

Beispiel: JSON-Objekt von Hand erstellen

public static void main(String[] args) {

JsonObject personObject = Json.createObjectBuilder()

.add("name", "Bruce Banner")

.add("alter", 44)

.add("firma",

Json.createObjectBuilder()

.add("name", "Shield")

.add("ort", "unbekannt")

.build())

.add("freunde",

Json.createArrayBuilder()

.add("James Howlett")

.add("Ben Grimm")

.build())

.build();

System.out.println("Object: " + personObject);

}

Object:

{"name":"Bruce

Banner","alter":44,"f

irma":{"name":"Shield

","ort":"unbekannt"},

"freunde":["James

Howlett","Ben

Grimm"]}

Komponentenbasierte Software-Entwicklung

Page 83: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

392

Ausschnitt Klassendiagramm

Komponentenbasierte Software-Entwicklung

Page 84: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

393

Beispiel: Stream-Bearbeitung von JSON

// daten: siehe JSON lesen

JsonParser parser = Json

.createParser(new StringReader(daten));

while (parser.hasNext()) {

Event event = parser.next();

System.out.print(event + ": ");

switch (event) {

case KEY_NAME:

System.out.print(parser.getString());

break;

case VALUE_NUMBER:

System.out.print(parser.getInt());

break;

}

System.out.println("");

}

START_OBJECT:

KEY_NAME: name

VALUE_STRING:

KEY_NAME: alter

VALUE_NUMBER: 42

KEY_NAME: firma

START_OBJECT:

KEY_NAME: name

VALUE_STRING:

KEY_NAME: ort

VALUE_STRING:

END_OBJECT:

KEY_NAME: freunde

START_ARRAY:

VALUE_STRING:

VALUE_STRING:

VALUE_NUMBER: 42

END_ARRAY:

END_OBJECT:Komponentenbasierte Software-Entwicklung

Page 85: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

394

Binding

• Binding schafft automatische Umwandlungsmöglichkeit von A nach B und von B nach A

• ohne Binding muss die Umwandlung (marshalling) manuell erfolgen, bei Netztransport ggfls. Rückumwandlung notwendig (unmarshalling)

• Java-Objekt von und nach XML löst JAXB

• JSR 222: JavaTM Architecture for XML Binding (JAXB) 2.0, https://jcp.org/en/jsr/detail?id=222

• wichtig Umwandlungsprozess konfigurierbar

• Java-Objekt von und nach JSON noch nicht standardisiert (für JEE 8 angekündigt)

• Referenzimplementierung für Glassfish (Stand Ende 2013) ist MOXy (übersetzt JAXB-Annotationen nach JSON)

Komponentenbasierte Software-Entwicklung

Page 86: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

395

Beispiel: Vorbereitung einer Entitäts-Klasse für JSON

@XmlRootElement

public class Punkt implements Serializable {

private int x;

private int y;

public Punkt() {} // wichtig

public Punkt(int x, int y) {this.x = x; this.y = y;}

public int getX() {return x;}

public int getY() {return y;}

public void setX(int x) {this.x = x;}

public void setY(int y) {this.y = y;}

@Override

public String toString() {return "[" + x + "," + y + "]";}

}

Komponentenbasierte Software-Entwicklung

Page 87: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

396

Annotationen zur Steuerung der Übersetzung

@XmlElement(name=“rufname") // Key-Umbenennung

public String name;

@XmlTransient // nicht übertragen

public int alter;

• man beachte, dass man erhaltenes Objekt auch noch mit vorherigen Methoden modifizieren kann

• Übersetzung noch nicht standardisiert (aktuell MOXy, Teil von EclipseLink)

• da manuelle JsonObject-Erzeugung nicht sehr aufwändig und sehr flexibel, wird es gute Alternative bleiben

Komponentenbasierte Software-Entwicklung

Page 88: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

397

Hintergrund Web Services

• zentraler Wunsch: einfache Nutzung von Software über das Netz

• unabhängig wo sich ein Rechner befindet

• unabhängig von der Programmiersprache

SOAP-basierte WebServices

• jeder Service hat eindeutige Kennung (URI, Uniform Resource Identifier)

• Schnittstellenbeschreibung WSDL

• typisch: XML-basierte Kommunikationsprotokolle

• typisch: Verbindung mit SOA

• hier nicht wichtig, aber SOA ≠ SOAP ≠ Web Service

Komponentenbasierte Software-Entwicklung

Page 89: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

398

Hintergrund: Service Oriented Architecture

Service-

Verzeichnis

Service-

Anbieter

Service-

Nutzer

3. Anfragen

4. Antworten

SOAP

WSDL

HTTP

UDDI

Komponentenbasierte Software-Entwicklung

Page 90: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

399

Zwischenfazit SOA

• Vision: auf Grundlage von Geschäftsprozessmodellierungen kann individuelle Software für ein Unternehmen entstehen

• Realität: machbar, wenn alles auf einem Hersteller basiert

• Realität: UDDI hat in fast allen Projekten nicht stattgefunden (SOA ist auch Super Overhyped Acronym)

• aber: WebServices basierend auf SOAP haben als Kommunikationskonzept zentrale Bedeutung bekommen

• gilt als relativ langsam

• aber: Unternehmen nutzen es um MS-basierte Oberfläche mit JEE-realisiertem Server zu verbinden

Komponentenbasierte Software-Entwicklung

Page 91: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

400

RESTful (Representational State Transfer)

• Idee von der Interaktion zwischen Rechnern bleibt

• REST ist ein Architekturstil für verteilte Hypermedia-Systeme

• Protokoll: nutze Möglichkeiten von HTTP

– GET: lese Information (SELECT)

– POST: neue Information (INSERT)

– PUT: ändere Information (UPDATE)

– DELETE: lösche Information (DELETE)

• Klammern deuten Ähnlichkeit zu Datenbankoperationen an

• Grundlage: Dissertation Roy Fielding „Architectural Styles and the Design of Network-based Software Architectures “

• http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

Komponentenbasierte Software-Entwicklung

Page 92: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

401

(An)forderungen zur REST-Nutzung

• Adressierbarkeit: Jede Ressource eindeutig über URL identifizierbar

• Ressourcenorientierung: alle Anfragen beziehen sich auf Ressourcen, URL kann verarbeitenden Dienst und Ress-Id enthalten

• flexible Darstellung: maschinell lesbar, z. B: JSON, XML, HTML

• Zustandsbasiert: Interaktion entspricht endlichen Automaten (Interaktion führt zu Folgezustand, weitere Schritte klar definiert)

• Statuslos: Alle Infos zur Bearbeitung in Anfrage enthalten

• Standardisiert: Zugriff über standardisierte Operatoren (hier: Get, Post, Put, Delete, Patch, Head, Options)

• Literatur: D. Abts, Masterkurs Client/Server-Programmierung in Java, 4. Auflage, Springer Vieweg, 2015

Komponentenbasierte Software-Entwicklung

Page 93: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

402

Woher kommt „ Representational State Transfer“

Client fordert Information mit Hilfe einer URL (URI) an.

Eine Repräsentation der Information zusammen mit möglichen Bearbeitungsschritten, wird als Ergebnis zurückgegeben (z. B. in Form eines JSON-Objekts), Client hat Informationszustand.

Client nutzt Hyperlinks in Ergebnis um weitere Informationen anzufordern.

Neues Ergebnis versetzt Client in einen neuen Informationszustand.

ResourceClient

http://www.scrumsprinter.de/sprint/42

{ “id”: 42,

“name”: “Prototyp”,

“elemente”: [ …

Komponentenbasierte Software-Entwicklung

Page 94: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

403

HATEOAS – saubere REST-Architektur

„Hypermedia as the Engine of Application State“

• Client kennt nur die Basis-URI des Dienstes

• Server leitet durch Informationszustände der Anwendung durch Bekanntgabe von Wahlmöglichkeiten (Hyperlinks), genauer: welche Folgeaufrufe sind wie möglich

• HTTP-Kommunikationsprotokoll selbst bleibt zustandslos

• Grundregel: GET, PUT, DELETE (auch PATCH, HEAD, OPTIONS) sind idempotent; führen zum gleichen Ergebnis, egal wie oft sie im gleichen Informationszustand aufgerufen werden

• häufig genutzter Trick: POST auch zur partiellen Aktualisierung

Komponentenbasierte Software-Entwicklung

Page 95: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

404

Richardson Maturity Model

• Bewertung inwiefern WebService REST-Bedingungen erfüllt

• Stufe 0: RESTless, nutzt URI, HTTP als Transportprotokoll für RPC-Aufrufe

• Stufe 1: Ressourcen, jede Ressource hat URI, diese wird zur direkten Ansprache genommen

• Stufe 2: HTTP-Verben, GET, POST, … werden in der von REST geforderten Form genutzt, Antworten mit HTTP-Statuscodes

• Stufe 3: RESTful - Hypermedia, zustandsbasiert, klare Information in welchem Zustand sich Bearbeitung befindet und welche nächsten Aktionen (mit Parameterbereichen) möglich sind

• Anmerkung: Diskutabel, aber oft liegt die Praxis zwischen Level 1 und 3, oft 2 (RESTbasiert)

• Literatur: z. B. https://martinfowler.com/articles/richardsonMaturityModel.html

Komponentenbasierte Software-Entwicklung

Page 96: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

405

HATEOAS: Beispiel

Komponentenbasierte Software-Entwicklung

z1

z2

b b

a

a

Page 97: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

406

Wer nutzt es (Beispiele)?

• Hinweis: Öfter wird gegen die geforderte Reinform von RESTful WebServices verstoßen, und normale Anfragemöglichkeit mit GET als RESTful oder REST-basiert bezeichnet

• Google Maps

• Google AJAX Search API

• Yahoo Search API

• Amazon WebServices

Komponentenbasierte Software-Entwicklung

Page 98: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

407

Standardisierung in Java

viele Implementierungen

• Restlet http://www.restlet.org/

• Apache CXF http://cxf.apache.org/

• Project Zero http://www.projectzero.org

• GlassFish Jersey https://jersey.dev.java.net/ (Referenz)

• JBoss RESTeasy http://www.jboss.org/resteasy/

Standardisierung für Java:

• JSR 311: JAX-RS (10.10.2008)

• JSR 339: JAX-RS 2.0 (24.5.2013)

• JSR 370: JavaTM API for RESTful Web Services (JAX-RS 2.1), (22.8.2017), https://www.jcp.org/en/jsr/detail?id=370

Komponentenbasierte Software-Entwicklung

Page 99: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

408

JAX-RS aktivieren

• in JEE-aware Servern reicht folgendes ausimport javax.ws.rs.ApplicationPath;

import javax.ws.rs.core.Application;

@ApplicationPath("resources")

public class ApplicationConfig extends Application {

}

• statt „resources“ auch „“ möglich, wenn nicht gleichzeitig JSF genutzt wird („Pfade beißen sich“)

• ist generell im .war-File

• sonst Konfiguration als Servlet nötig

• Beschreibung in web.xml

Komponentenbasierte Software-Entwicklung

Page 100: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

409

JAX-RS aktivieren (Alternative)

@ApplicationPath("resources")

public class ApplicationConfig extends Application {

@Override

public Set<Class<?>> getClasses() {

Set<Class<?>> resources = new java.util.HashSet<>();

try { // customize Jersey 2.0 JSON provider:

Class jsonProvider = Class

.forName("org.glassfish.jersey.moxy.json.MoxyJsonFeature");

resources.add(jsonProvider);

} catch (ClassNotFoundException ex) {}

addRestResourceClasses(resources);

return resources;

}

private void addRestResourceClasses(Set<Class<?>> resources) {

resources.add(hello.HelloWorld.class);

}

}

Anbieter von Services

Komponentenbasierte Software-Entwicklung

Page 101: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

410

erste REST-basierte WebServices

@Path("/helloworld")

public class HelloWorld {

public HelloWorld() { }

@GET

@Produces("text/html")

public String getHtml() {

return "<html><body><h1>Hello, World!!</h1></body></html>";

}

@GET

@Produces(MediaType.TEXT_PLAIN)

public String getText() {

return "Tach Welt";

}

}Komponentenbasierte Software-Entwicklung

Page 102: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

411

detaillierte Analyse@Path("/helloworld")

• Gibt Aufrufpfad an, hier resources/helloworld

• Pfad wird an Projektpfad, z. B. /vlRESTAnfang, angehängt

• könnte auch nur an einzelnen Methoden stehen

• kann auch zusätzlich an Methoden stehen, so dass sich der Pfad verlängert

@GET

@Produces("text/html")

• Annotationen aus javax.ws.rs

• HTTP-Befehl und Ergebnistyp (mögliche Ergebnistypen, mehrere MIME-Typen [Multipurpose Internet Mail Extension])

• nachfolgender Methodenname spielt keine Rolle!

Komponentenbasierte Software-Entwicklung

Page 103: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

412

direkter Aufruf

• bei GET ist direkter Aufruf im Browser möglich

• aber, das ist ein sehr sehr untypisches Szenario

• typisch:

– Aufruf direkt aus einer Web-Seite, meist mit JavaScript

– Aufruf aus anderer Software heraus mit Mitteln der jeweiligen Programmiersprache (z. B. java.net.URL)

• NetBeans: kein Haken bei „Display Browser on Run“

Komponentenbasierte Software-Entwicklung

Page 104: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

413

Detaillierte Analyse mit cURL

• generell jedes Programm zur Erzeugung von HTTP-Aufrufen und Analyse der Ergebnisse geeignet

• Kommando-Zeile mit cURLhttp://curl.haxx.se/download.html

• Für etwaige Parameter muss auch URL in Anführungsstrichen stehen

• viele Browser unterstützen direkt bei solchen Tests

• weiteres Tool: Postman https://www.getpostman.com/Komponentenbasierte Software-

Entwicklung

Page 105: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

414

Nutzung automatischen Marshallings - GET

• verschiedene Rückgabetypen bedienbar (praktisch sinnvoll?)@GET

@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})

public Punkt getJSon2() {

return new Punkt(42,43); // war @XMLRootElement annotiert

}

Komponentenbasierte Software-Entwicklung

Page 106: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

415

Nutzung automatischen Unmarshallings - POST

@POST

@Produces(MediaType.TEXT_PLAIN)

@Consumes(MediaType.APPLICATION_JSON)

public String postit(Punkt p){

System.out.println(p);

return "ok";

}

• weitere Parameter im JSON-Objekt führen zu Fehlern

Komponentenbasierte Software-Entwicklung

Page 107: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

416

zentrale Klassen Client und Response

• RESTful Web Services werden typischerweise aus anderer Software aufgerufen

• dies ist natürlich auch in Java möglich; vor JAX-RS 2.0 aber proprietäre Lösungen der Anbieter

• https://jersey.java.net/download.html

• jetzt Klasse javax.ws.rs.client.Client

• Bei der Nutzung von RESTful Web Services können verschiedene Klassen als Typen für Parameter und Rückgabe genutzt werden

• Hilfreich ist Klasse javax.ws.rs.core.Response

• Server erzeugt Response-Objekt

• Client kann problemlos Response-Objekt lesen

• Response ist ein Stream, muss auch geschlossen werden

Komponentenbasierte Software-Entwicklung

Page 108: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

417

Hilfsmethode zur genaueren Analyse von Response

private void details(Response res) {

System.out.println("-----------------\n"

+ "AllowedMethods : " + res.getAllowedMethods() + "\n"

+ "Entity Class: " + res.getEntity().getClass() + "\n"

+ "Language : " + res.getLanguage() + "\n"

+ "Location : " + res.getLocation() + "\n"

+ "Mediatype : " + res.getMediaType() + "\n"

+ "Links : " + res.getLinks() + "\n"

+ "Status : " + res.getStatus() + "\n"

+ "Date : " + res.getDate() + "\n"

+ "Class : " + res.getClass() + "\n"

+ "Inhalt : " + res.readEntity(String.class));

res.close();

}

Komponentenbasierte Software-Entwicklung

Page 109: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

418

Kleine Beispiele (1/7)

• Anmerkung: Zeigt Service-Nutzung, zeigt nichts von RESTpublic class ClientAnalyse {

private Client client;

private WebTarget userTarget;

public ClientAnalyse() {

Client client = ClientBuilder.newClient();

userTarget = client

.target("http://localhost:8080/vlRESTAnfang"

+ "/resources/helloworld");

}

Komponentenbasierte Software-Entwicklung

Page 110: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

419

Kleine Beispiele (2/7)

public void analyse1() {

Response res = userTarget.request("text/html").get();

details(res);

}

AllowedMethods : []

Entity Class: class org.glassfish.jersey.client.HttpUrlConnector$2

Language : null

Location : null

Mediatype : text/html

Links : []

Status : 200

Date : Fri Dec 18 15:39:22 CET 2015

Class : class org.glassfish.jersey.client.InboundJaxrsResponse

Inhalt : <html lang="en"><body><h1>Hello, World!!</h1></body></html>

Komponentenbasierte Software-Entwicklung

Page 111: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

420

Kleine Beispiele (3/7)

public void analyse1() {

Response res = userTarget.request(MediaType.TEXT_PLAIN).get();

details(res);

}

AllowedMethods : []

Entity Class: class org.glassfish.jersey.client.HttpUrlConnector$2

Language : null

Location : null

Mediatype : text/plain

Links : []

Status : 200

Date : Wed May 14 18:55:35 CEST 2014

Class : class org.glassfish.jersey.client.ScopedJaxrsResponse

Inhalt : <html lang="en"><body><h1>Hello, World!!</h1></body></html>

Komponentenbasierte Software-Entwicklung

Page 112: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

421

Kleine Beispiele (4/7)

public void analyse3() {

Response res = userTarget

.request(MediaType.APPLICATION_JSON).get();

details(res);

}

AllowedMethods : []

Entity Class: class org.glassfish.jersey.client.HttpUrlConnector$1

Language : null

Location : null

Mediatype : application/json

Links : []

Status : 200

Date : Wed May 14 18:55:35 CEST 2014

Class : class org.glassfish.jersey.client.ScopedJaxrsResponse

Inhalt : {"x":42,"y":43}

Komponentenbasierte Software-Entwicklung

Page 113: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

422

Kleine Beispiele (5/7)

public void analyse4() {

Response res = userTarget.request(MediaType.TEXT_XML).get();

details(res);

}

AllowedMethods : []

Entity Class: class org.glassfish.jersey.client.HttpUrlConnector$1

Language : null

Location : null

Mediatype : text/xml

Links : []

Status : 200

Date : Wed May 14 19:08:13 CEST 2014

Class : class org.glassfish.jersey.client.ScopedJaxrsResponse

Inhalt : <?xml version="1.0" encoding="UTF-8"

standalone="yes"?><punkt><x>42</x><y>43</y></punkt>

Komponentenbasierte Software-Entwicklung

Page 114: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

423

Kleine Beispiele (6/7)

public void analyse5() {

Builder buil = this.userTarget.request(MediaType.TEXT_PLAIN);

Entity e = Entity.entity(new Punk(3, 4)

, MediaType.APPLICATION_JSON);

System.out.println(e + " : " + e.getEntity());

String res = buil.post(e, String.class);

System.out.println(res);

}

javax.ws.rs.client.Entity@52aa911c : [3,4]

ok

• Anmerkung: Klasse Punk wie Punkt, sogar ohne XMLRootElement-Annotation , aber Serializable

Komponentenbasierte Software-Entwicklung

Page 115: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

424

Kleine Beispiele (7/7)

public void analyse6() {

Builder buil = this.userTarget.request(MediaType.TEXT_PLAIN);

Entity e = Entity.json(new Punk(2,3));

System.out.println(e + " : " + e.getEntity());

String res = buil.post(e, String.class);

System.out.println(res);

}

Entity{entity=[2,3], variant=Variant[mediaType=application/json,

language=null, encoding=null], annotations=[]} : [2,3]

ok

• Klasse Entity bietet einige Marshalling-Methoden

Komponentenbasierte Software-Entwicklung

Page 116: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

425

flexible Dienststrukturen

• generell soll man aus Antworten auf weitere Abfragemöglichkeiten schließen können

• /helloworld/kunden/

Frage nach Kunden: Sammlung der Namen aller Kunden

• /helloworld/kunden/Hoeness/

Frage nach Kunden mit Namen: alle Eigenschaften des Kunden

• /helloworld/kunden/Hoeness/konten

Frage nach Konten eines benannten Kunden: Sammlung aller Konten des Kunden

• /helloworld/kunden/Hoeness/konten/42

Frage nach Kontonummer eines benannten Kunden: alle Eigenschaften des Kontos dieses Kunden

Komponentenbasierte Software-Entwicklung

Page 117: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

426

Beispiel: Umsetzung von Pfaden (1/4)

@Path("helloworld")

public class HelloWorld {

// Kundenname, Sammlung von Konten (Nummer, Betrag)

private Map<String, Map<Integer, Long> > kunden;

public HelloWorld() {

// zufaellige Beispieldaten

Map<Integer,Long> tmp = new HashMap<>();

tmp.put(42,32000000L);

kunden = new HashMap<>();

kunden.put("Hoeness", tmp);

}

Komponentenbasierte Software-Entwicklung

Page 118: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

427

Beispiel: Umsetzung von Pfaden (2/4)

@GET

@Produces(MediaType.APPLICATION_JSON)

@Path("/kunden/{user}/konten/{id}")

public JsonObject getKontostand(

@PathParam("user") String user

, @PathParam("id") int id) {

JsonObjectBuilder erg = Json.createObjectBuilder();

Map<Integer,Long> kunde = kunden.get(user);

if(kunde == null){

return erg.add("fehler", "kein Kunde").build();

}

Long summe = kunde.get(id);

if(summe == null){

return erg.add("fehler", "kein Konto").build();

}

return erg.add("summe", summe).build();

}Komponentenbasierte Software-

Entwicklung

Page 119: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

428

Beispiel: Umsetzung von Pfaden (3/4)

public static void main(String[] a){

String[] verdaechtig = {"Rummenigge", "Hoeness"};

int[] nummern = {42,43};

Client client = ClientBuilder.newClient();

for(String v:verdaechtig){

for (int n:nummern){

WebTarget target = client.target("http://localhost:8080"

+ "/vlRESTAnfang/resources/helloworld/kunden/"

+ v + "/konten/" + n);

JsonObject erg = target

.request(MediaType.APPLICATION_JSON)

.get(JsonObject.class);

System.out.println(erg);

}

}

}

Komponentenbasierte Software-Entwicklung

Page 120: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

429

Beispiel: Umsetzung von Pfaden (4/4)

{"fehler":"kein Kunde"}

{"fehler":"kein Kunde"}

{"summe":32000000}

{"fehler":"kein Konto"}

Komponentenbasierte Software-Entwicklung

Page 121: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

430

Umsetzung von Pfaden

@Path("/kunden/{user}/konten/{id}")

• Einbau von Pfadvariablen, auf die in Parameterliste mit @PathParam("user") zugegriffen werden kann

• einfache Java-Typen, typischerweise int, long, String nutzbar; Konvertierung automatisch

• Pfadvariablen in der Klassenannotation können dann in jedem Methodenkopf genutzt werden

• Pfadvariablen können in @Path doppelt vorkommen und müssen dann gleichen Wert bei Nutzung haben

• im Hinterkopf: wenn HTTPS, dann auch User-Token so übertrag- und später prüfbar (Sicherheit)

• im Hinterkopf: individueller Wert für jeden Nutzer, der E-Mail mit so einem Link erhält

Komponentenbasierte Software-Entwicklung

Page 122: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

431

Externer Service zur Analyse von IPs (1/4)

private static void zeigeJsonObjekt(JsonObject js){

for(String key:js.keySet()){

System.out.println(key+ ": " + js.get(key));

}

}

public static void main(String[] s){

String SERVICE = "http://freegeoip.net/json";

Client client = ClientBuilder.newClient();

WebTarget wt = client.target(SERVICE);

Invocation.Builder invoc = wt.request();

JsonObject ergebnis = invoc.get(JsonObject.class);

zeigeJsonObjekt(ergebnis);

zeigeJsonObjekt(client.target(SERVICE+"/www.bild.de")

.request().get(JsonObject.class));

}Komponentenbasierte Software-Entwicklung

Page 123: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

432

Externer Service zur Analyse von IPs (2/4)

ip: "84.155.86.93"

country_code: "DE"

country_name: "Germany"

region_code: "NI"

region_name: "Lower Saxony"

city: "Neuenkirchen"

zip_code: "49586"

time_zone: "Europe/Berlin"

latitude: 52.4167

longitude: 7.85

metro_code: 0

ip: "72.247.9.43"

country_code: "US"

country_name: "United States"

region_code: "MA"

region_name: "Massachusetts"

city: "Cambridge"

zip_code: "02142"

time_zone: "America/New_York"

latitude: 42.3626

longitude: -71.0843

metro_code: 506

Komponentenbasierte Software-Entwicklung

Page 124: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

433

Externer Service zur Analyse von IPs (3/4)

public static void main(String[] st){

Client client = ClientBuilder.newClient();

WebTarget wt = client.target("http://freegeoip.net/json");

Invocation.Builder invoc = wt.request();

Response ergebnis = invoc.get();

System.out.println(ergebnis);

ergebnis.bufferEntity(); // sonst Fehler bei 42

System.out.println(ergebnis.getEntity());

for(String s:ergebnis.getHeaders().keySet()){

System.out.println(s +": " + ergebnis.getHeaders().get(s));

}

System.out.println(ergebnis.readEntity(JsonObject.class));

System.out.println(ergebnis.getEntity().getClass()); //42

ergebnis.close();

}Komponentenbasierte Software-

Entwicklung

Page 125: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

434

Externer Service zur Analyse von IPs (4/4)

ScopedJaxrsResponse{ClientResponse{method=GET,

uri=http://freegeoip.net/json, status=200, reason=OK}}

java.io.ByteArrayInputStream@6d420a24

Date: [Wed, 14 May 2014 17:48:10 GMT]

Access-Control-Allow-Origin: [*]

Content-Length: [222]

Content-Type: [application/json]

{"ip":"93.196.192.46","country_code":"DE","country_name":"Germany","

region_code":"07","region_name":"Nordrhein-

Westfalen","city":"Hopsten","zipcode":"","latitude":52.3833,"longitu

de":7.6167,"metro_code":"","area_code":""}

class java.io.ByteArrayInputStream

Komponentenbasierte Software-Entwicklung

Page 126: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

435

Übergabe von Aufrufparametern (1/2)

@GET

@Produces(MediaType.APPLICATION_JSON)

@Path("/rechnen")

public JsonObject machMathe(

@QueryParam("op1") int op1,

@QueryParam("op2") int op2,

@DefaultValue("plus")

@QueryParam("operator") String operator) {

JsonObjectBuilder erg = Json.createObjectBuilder();

if(operator.equals("minus")){

return erg.add("operator", operator)

.add("ergebnis", (op1-op2)).build();

}

return erg.add("operator", "plus")

.add("ergebnis", (op1+op2)).build();

}

Komponentenbasierte Software-Entwicklung

Page 127: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

436

Übergabe von Aufrufparametern (2/2)

Komponentenbasierte Software-Entwicklung

Page 128: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

437

Dienstnutzung mit Aufrufparametern (1/2)

public static void main(String[] s) {

String SERVICE

= "http://maps.googleapis.com/maps/api/geocode/json";

Client client = ClientBuilder.newClient();

WebTarget wt = client.target(SERVICE +

"?address=Quakenbrueck&sensor=false");

Invocation.Builder invoc = wt.request();

JsonObject ergebnis = invoc.get(JsonObject.class);

System.out.println(ergebnis);

JsonObject details = ((JsonArray)ergebnis.get("results"))

.getJsonObject(0);

JsonObject position= (JsonObject)

((JsonObject)details.get("geometry")).get("location");

System.out.println(position);

}

Komponentenbasierte Software-Entwicklung

Page 129: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

438

Dienstnutzung mit Aufrufparametern (2/2)

{"results":[{"address_components":[{"long_name":"Quakenbrück","

short_name":"Quakenbrück","types":["locality","political"]},{"l

ong_name":"Lower

Saxony","short_name":"NDS","types":["administrative_area_level_

1","political"]},{"long_name":"Germany","short_name":"DE","type

s":["country","political"]}],"formatted_address":"Quakenbrück,

Germany","geometry":{"bounds":{"northeast":{"lat":52.6967289,"l

ng":8.0344312},"southwest":{"lat":52.65917049999999,"lng":7.903

767999999999}},"location":{"lat":52.675599,"lng":7.950777699999

999},"location_type":"APPROXIMATE","viewport":{"northeast":{"la

t":52.6967289,"lng":8.0344312},"southwest":{"lat":52.6591704999

9999,"lng":7.903767999999999}}},"place_id":"ChIJqfqve3Zpt0cRIqf

jZXu8LGw","types":["locality","political"]}],"status":"OK"

{"lat":52.675599,"lng":7.950777699999999}

Komponentenbasierte Software-Entwicklung

Page 130: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

439

UriInfo (1/2)

@Path("ana")

@Stateless

public class Analyse {

@Context

private UriInfo uriInfo;

private final static Logger LOGGER = Logger

.getLogger(Analyse.class.getSimpleName());

@GET

@Produces(MediaType.TEXT_PLAIN)

public String getText() {

LOGGER.info("in getText");

LOGGER.info(this.uriInfo.getAbsolutePath().toString());

Komponentenbasierte Software-Entwicklung

Page 131: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

440

UriInfo (2/2)

LOGGER.info(this.uriInfo.getPath());

LOGGER.info(this.uriInfo.getRequestUri().toString());

for (String s:this.uriInfo.getQueryParameters().keySet()){

LOGGER.info(s+ ": "

+ this.uriInfo.getQueryParameters().get(s));

}

return "hai";

}

INFO: in getText

INFO: http://localhost:8080/resources/ana

INFO: /ana

INFO: http://localhost:8080/resources/ana?x=Hai&text=42

INFO: text: [42]

INFO: x: [Hai]

Komponentenbasierte Software-Entwicklung

Page 132: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

441

Aufgabe

• Ergänze Mitarbeiterverwaltung um REST-Schnittstelle

• setze auf Basis-Architektur auf

Komponentenbasierte Software-Entwicklung

Page 133: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

442

Ergänzungen (1/3)

• Klassen zum Ergebnisaustausch JSON-fähig machen (Annotation oder von Hand)

• typischerweise toJsonObject(): JSsonObject, ggfls. auch Rückwandlung

• z. B. in MitarbeiterDTO:

public JsonObject toJSonObject() {

JsonObjectBuilder js = Json.createObjectBuilder();

js.add("minr", this.getMinr())

.add("vorname", this.getVorname())

.add("nachname", this.getNachname())

.add("alter", this.getAlter())

.add("befehl", this.befehl); // hier ignorieren

return js.build();

}

Komponentenbasierte Software-Entwicklung

Page 134: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

443

Ergänzungen (2/3)

• in Resultatpublic JsonObject toJSonObject() {

JsonObjectBuilder js = Json.createObjectBuilder();

js.add("ergebnis", this.isErgebnis())

.add("kommentar", this.getKommentar());

return js.build();

}

• REST einrichten (Pfad „r“ nur, da er hier nicht leer sein soll, da zusammen mit JSF Applikation installiert, die bei Nutzung des einfachen Pfads aufgerufen wird)

@ApplicationPath("r")

public class ApplicationConfig extends Application { }

Komponentenbasierte Software-Entwicklung

Page 135: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

444

Ergänzungen (3/3)

• Methode wäre auch in MitarbeiterDTO sinnvoll

• hier in MitarbeiterRESTBoundary Null-Prüfung möglichprivate JsonObject toJSonObject(MitarbeiterDTO m) {

if (m == null) {

return null;

}

JsonObjectBuilder js = Json.createObjectBuilder();

js.add("minr", m.getMinr())

.add("vorname", m.getVorname())

.add("nachname", m.getNachname())

.add("alter", m.getAlter())

.add("link", uriInfo.getAbsolutePathBuilder()

.build().getPath());

return js.build();

}Komponentenbasierte Software-

Entwicklung

Page 136: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

445

REST-Schnittstelle (1/5)

@Stateless // oder @Singleton

@Path("")

public class MitarbeiterRESTBoundary {

@Inject

private Controller controller;

@Context

private UriInfo uriInfo;

@GET

@Produces({MediaType.APPLICATION_JSON})

@Path("/mitarbeiter/{minr}")

public JsonObject mitarbeiter(@PathParam("minr") int minr) {

return this.toJSonObject(this.controller.mitarbeiter(minr));

}

Komponentenbasierte Software-Entwicklung

Page 137: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

446

REST-Schnittstelle (2/5)

@GET

@Produces({MediaType.APPLICATION_JSON})

@Path("/mitarbeiter")

public JsonObject alleMitarbeiter() {

List<MitarbeiterDTO> alle = this.controller.alleMitarbeiter();

JsonArrayBuilder elemente = Json.createArrayBuilder();

alle.forEach(m -> elemente.add(this.toJSonObject(m)));

return Json.createObjectBuilder()

.add("mitarbeiter", elemente)

.add("self", uriInfo.getAbsolutePathBuilder()

.path("/").build().getPath())

.build();

}

Komponentenbasierte Software-Entwicklung

Page 138: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

447

REST-Schnittstelle (3/5)

@POST

@Produces(MediaType.APPLICATION_JSON)

@Consumes(MediaType.APPLICATION_JSON)

@Path("/mitarbeiter")

public JsonObject hinzufuegen(JsonObject jo) {

MitarbeiterDTO ma = new MitarbeiterDTO(0

,jo.getString("vorname")

, jo.getString("nachname"), "","");

return this.controller.save(ma).toJSonObject();

}

// hier wird das Protokoll fuer den Nutzer festgelegt,

// es wird JSON-Objekt mit den angegebenen Attributen gefordert

// (Exception, wenn nicht vorhanden; besser behandeln)

Komponentenbasierte Software-Entwicklung

Page 139: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

448

REST-Schnittstelle (4/5)

@PUT

@Produces(MediaType.APPLICATION_JSON)

@Consumes(MediaType.APPLICATION_JSON)

@Path("/mitarbeiter/{minr}")

public JsonObject aktualisieren(@PathParam("minr") int minr

, JsonObject jo) {

MitarbeiterDTO ma = this.controller.mitarbeiter(minr);

if (ma == null){

return (new Resultat(false, "kein Mitarbeiter mit minr "

+ minr)).toJSonObject();

}

ma.setVorname(jo.getString("vorname"));

ma.setNachname(jo.getString("nachname"));

return this.controller.update(ma).toJSonObject();

}Komponentenbasierte Software-

Entwicklung

Page 140: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

449

REST-Schnittstelle (5/5)

@DELETE

@Produces(MediaType.APPLICATION_JSON)

@Consumes(MediaType.APPLICATION_JSON)

@Path("/mitarbeiter/{minr}")

public JsonObject loeschen(@PathParam("minr") int minr) {

MitarbeiterDTO ma = this.controller.mitarbeiter(minr);

if (ma == null){

return (new Resultat(false

, "Mitarbeiter gelöscht (nicht existent)" + minr))

.toJSonObject();

}

return this.controller.delete(ma).toJSonObject();

}

}

Komponentenbasierte Software-Entwicklung

Page 141: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

450

Beispiel-Client (1/7)

• Client kann in beliebiger Sprache geschrieben sein

• Hier Beispiel mit Wiederverwendung, Frontend aus Mitarbeiterprojekt wird wieder genutzt, neue Controllerschicht, die REST nutzt

• Client schreibt eigene Mitarbeiterklasse (hier vereinfachend übernommen)

Komponentenbasierte Software-Entwicklung

Page 142: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

451

Beispiel-Client (2/7)

@Dependent

public class ControllerRESTFrontend implements Serializable {

private final static String MITARBEITER

= "http://localhost:8080/kbseMitarbeiterverwaltung"

+ "/r/mitarbeiter";

private Client client;

private WebTarget wt;

@PostConstruct

public void init() {

this.client = ClientBuilder.newClient();

this.wt = client.target(MITARBEITER);

}

Komponentenbasierte Software-Entwicklung

Page 143: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

452

Beispiel-Client (2/7)

@Dependent

public class ControllerRESTFrontend implements Serializable {

private final static String MITARBEITER

= "http://localhost:8080/kbseMitarbeiterverwaltung"

+ "/r/mitarbeiter";

private Client client;

private WebTarget wt;

@PostConstruct

public void init() {

this.client = ClientBuilder.newClient();

this.wt = client.target(MITARBEITER);

}

Komponentenbasierte Software-Entwicklung

Page 144: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

453

Beispiel-Client (3/7)public List<MitarbeiterDTO> alleMitarbeiter() {

Invocation.Builder build = this.wt

.request(MediaType.APPLICATION_JSON);

JsonObject ergebnis = build.get(JsonObject.class);

JsonArray array = ergebnis.getJsonArray("mitarbeiter");

List<MitarbeiterDTO> alle = new ArrayList<>();

for (JsonValue val : array) {

JsonObject js = (JsonObject) val;

MitarbeiterDTO tmp = new MitarbeiterDTO();

tmp.setAlter(js.getString("alter"));

tmp.setMinr(js.getInt("minr"));

tmp.setNachname(js.getString("nachname"));

tmp.setVorname(js.getString("vorname"));

alle.add(tmp);

}

return alle;

}

Komponentenbasierte Software-Entwicklung

Page 145: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

454

Beispiel-Client (4/7)

public String save(MitarbeiterDTO m) {

Invocation.Builder build = this.wt

.request(MediaType.APPLICATION_JSON);

Entity entity = Entity.entity(this.toJSonObject(m),

MediaType.APPLICATION_JSON);

try {

JsonObject ergebnis = build.post(entity

, JsonObject.class);

return ergebnis.getString("kommentar");

} catch (Exception e) {

return e.toString();

}

}

Komponentenbasierte Software-Entwicklung

Page 146: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

455

Beispiel-Client (5/7)

public String update(MitarbeiterDTO m) {

WebTarget wt = client.target(MITARBEITER + "/" + m.getMinr());

Invocation.Builder build = wt

.request(MediaType.APPLICATION_JSON);

Entity entity = Entity.entity(this.toJSonObject(m)

, MediaType.APPLICATION_JSON);

try {

JsonObject ergebnis = build.put(entity, JsonObject.class);

return ergebnis.getString("kommentar");

} catch (Exception e) {

return e.toString();

}

}

Komponentenbasierte Software-Entwicklung

Page 147: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

456

Beispiel-Client (6/7)

public String delete(MitarbeiterDTO m) {

WebTarget wt = client.target(MITARBEITER + "/" + m.getMinr());

Invocation.Builder build = wt

.request(MediaType.APPLICATION_JSON);

try {

JsonObject ergebnis = build.delete(JsonObject.class);

return ergebnis.getString("kommentar");

} catch (Exception e) {

return e.toString();

}

}

Komponentenbasierte Software-Entwicklung

Page 148: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

457

Beispiel-Client (7/7)

public MitarbeiterDTO mitarbeiter(int minr) {

WebTarget wt = client.target(MITARBEITER + "/" + minr);

Invocation.Builder build = wt

.request(MediaType.APPLICATION_JSON);

try {

JsonObject jo = build.get(JsonObject.class);

return MitarbeiterDTO.toObject(jo);

} catch (Exception e) {

return null;

}

}

}

Komponentenbasierte Software-Entwicklung

Page 149: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

458

Variante JavaScript-Client (1/10)

• JavaScript zentrale Sprache in den Browsern

• ursprünglich nur für kleine Aufgaben konzipiert (was man immer spürt)

• Standardisiert (ECMA-Script)

• Standard von keinem Browser konsequent eingehalten; es werden Browser-Switches benötigt

• Bibliotheken können Browser-Abhängigkeit teilweise wegkapseln

• viele sehr kreative, oft inkompatible (oft auch mit sich selbst in Versionssprüngen) Bibliotheken

• fast saubere Architektur möglich, leider selten

• hier nur sehr naiver Code ohne Tricks als Fallstudie

Komponentenbasierte Software-Entwicklung

Page 150: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

459

Variante JavaScript-Client (2/10)

Komponentenbasierte Software-Entwicklung

Page 151: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

460

Variante JavaScript-Client (3/10) – index.html (1/2)<!DOCTYPE html>

<html>

<head>

<title>REST Client f&uuml;r Mitarbeiter</title>

<meta http-equiv="Content-Type"

content="text/html; charset=UTF-8">

<script type="text/javascript" src="js/ws.js"></script>

</head>

<body>

<form name="felder">

<span id="pminr">Mitarbeiternummer wird vom

System vergeben</span>

<input id="minr" type="hidden">

<table border='0'>

<tr>

<td>Vorname:</td>

<td><input type="text" id="vorname"></td>

</tr>Komponentenbasierte Software-Entwicklung

Page 152: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

461

Variante JavaScript-Client (4/10) – index.html (2/2)<tr>

<td>Nachname:</td>

<td><input type="text" id="nachname"></td>

</tr>

<tr>

<td><input type="button" value="uebernehmen"

onClick="sende();"> </td>

<td><input type="button" id="abbrechen"

value="abbrechen" onClick="abbruch();"

style=" display: none;"></td>

</tr>

</table>

<span id="kommentar"></span><br>

<div id="mitarbeiter" style="background-color: white;

margin:5px;">

</div>

</form>

</body>

</html>

Komponentenbasierte Software-Entwicklung

Page 153: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

462

Variante JavaScript-Client (5/10) window.onload = function () {

laden();

}

PFAD =

"http://localhost:8080/kbseMitarbeiterverwaltung/r/mitarbeiter/";

function laden(){

var xhttp = new XMLHttpRequest();

xhttp.open("GET", PFAD, false);

xhttp.setRequestHeader("Content-Type", "application/json");

xhttp.send();

var response = JSON.parse(xhttp.responseText);

document.getElementById("mitarbeiter").innerHTML

= table(response.mitarbeiter);

}

Komponentenbasierte Software-Entwicklung

Page 154: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

463

Variante JavaScript-Client (6/10) function table(daten) {

data = daten;

var erg = "<table border='0'>";

erg += "<tr><th>Minr</th><th>Vorname</th><th>Nachname</th>";

erg += "<th>Alter</th><th></th></tr>";

for (var i = 0; i < data.length; i++) {

erg += "<tr>";

erg += "<td>" + data[i].minr + "</td>";

erg += "<td>" + data[i].vorname + "</td>";

erg += "<td>" + data[i].nachname + "</td>";

erg += "<td>" + data[i].alter + "</td>";

erg += "<td><input type='button' value='editieren' "

+ "onClick='edit(" + i + ");'></td>";

erg += "<td><input type='button' value='loeschen' "

+ "onClick='loeschen(" + i + ");'></td>";

erg += "</tr>";

}

erg += "</table>";

return erg;

}

Komponentenbasierte Software-Entwicklung

Page 155: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

464

Variante JavaScript-Client (7/10) function sende() {

var xhttp = new XMLHttpRequest();

var ma = {

vorname: document.getElementById('vorname').value,

nachname: document.getElementById('nachname').value,

minr: 0

};

// wenn „abbrechen“ sichtbar, dann ist es Aktualisierung

if (document.getElementById("abbrechen").style.display

=='block'){

ma.minr = parseInt(document.getElementById('minr').value, 10);

xhttp.open("PUT"

, PFAD + ma.minr

, false);

} else {

Komponentenbasierte Software-Entwicklung

Page 156: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

465

Variante JavaScript-Client (8/10) } else {

xhttp.open("POST"

, PFAD

, false);

}

xhttp.setRequestHeader("Content-Type", "application/json");

xhttp.send(JSON.stringify(ma));

var response = JSON.parse(xhttp.responseText);

document.getElementById("kommentar").innerHTML

= response.kommentar;

zuruecksetzen();

laden();

}

Komponentenbasierte Software-Entwicklung

Page 157: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

466

Variante JavaScript-Client (9/10) function abbruch() {

document.getElementById("abbrechen").style.display ='none';

zuruecksetzen();

}

function loeschen(i){

var xhttp = new XMLHttpRequest();

xhttp.open("DELETE"

, PFAD+data[i].minr

, false);

xhttp.setRequestHeader("Content-Type", "application/json");

xhttp.send();

var response = JSON.parse(xhttp.responseText);

laden();

document.getElementById("mitarbeiter").innerHTML

= table(response.mitarbeiter);

}Komponentenbasierte Software-

Entwicklung

Page 158: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

467

Variante JavaScript-Client (10/10) function zuruecksetzen(){

document.getElementById('vorname').value = '';

document.getElementById('nachname').value = '';

document.getElementById("abbrechen").style.display ='none';

document.getElementById("pminr").innerHTML

='Mitarbeiternummer wird vom System vergeben';

}

function edit(i) {

document.getElementById("minr").value = data[i].minr;

document.getElementById("pminr").innerHTML

= "Mitarbeiternummer: " + data[i].minr;

document.getElementById("vorname").value = data[i].vorname;

document.getElementById("nachname").value = data[i].nachname;

document.getElementById("abbrechen").style.display ='block';

document.getElementById("kommentar").innerHTML ='';

}Komponentenbasierte Software-

Entwicklung

Page 159: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

468

Vorherige Lösung ist schlechtes JavaScript

• Klasse XMLHttpRequest ist eine elementarer Baustein von Single-Page-Applications

• Nutzung erfolgt aktuell synchron, d. h. warten auf Ergebnis

• besser asynchron (asynchrones JavaScript und XML JSON)

• Projektaufbau davon unabhängig

Komponentenbasierte Software-Entwicklung

Page 160: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

469

Skizze – Umstellung auf asynchron (CallBack)

function laden(){

var xhttp = new XMLHttpRequest();

xhttp.open("GET"

, PFAD

, true); // true fuer asynchron

xhttp.setRequestHeader("Content-Type", "application/json");

xhttp.onreadystatechange = function() {

if (this.readyState == 4 && this.status == 200) {

var response = JSON.parse(this.responseText);

document.getElementById("mitarbeiter").innerHTML

= table(response.mitarbeiter);

} // Fehlerbehandlung fuer anderen this.status sinnvoll

};

xhttp.send();

}

Komponentenbasierte Software-Entwicklung

Page 161: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

470

WADL (1/3)

• Web Application Description Language

• XML-basierte Beschreibung angebotener Dienste

• generell soll HTTP-Befehl OPTIONS genutzt werden, um Übersicht zu erhalten

• Alle möglichen Dienste mit Parametern werden aufgeführt

• Dienstbeschreibungen können aus Annotation generiert werden

• Alternativ kann @OPTIONS-annotierte Methode realisiert werden (z. B. um Ausgabe zu verhindern)

• Bedeutung eher gering, für Werkzeuge basierend auf WADL-Services interessant; erkennen so Aktualisierungen

Komponentenbasierte Software-Entwicklung

Page 162: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

471

WADL (2/3) - Beispielmethode

@GET

@Produces("text/html")

public String getHtml() {

return "<html><body>Hello, World!!</body></html>";

}

<resources base="http://localhost:8080/resources/">

<resource path="helloworld">

<method id="getHtml" name="GET">

<response>

<representation mediaType="text/html"/>

</response>

</method>

...

Komponentenbasierte Software-Entwicklung

Page 163: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

472

WADL (3/3) – Beispiel aus Sprinter

<resources base="http://localhost:8080/Sprinter/resources/">

<resource path="sprints">

<method id="getSprints" name="GET">

<request>

<param xmlns:xs="http://www.w3.org/2001/XMLSchema"

name="von"

style="query" type="xs:int" default="-1"/>

<param xmlns:xs="http://www.w3.org/2001/XMLSchema"

name="bis"

style="query" type="xs:int" default="-1"/>

</request>

<response>

<representation mediaType="application/json"/>

</response>

</method>

<method id="hinzufuegen" name="POST">

<request>

<representation mediaType="application/json"/>

</request>

<response>

<representation mediaType="application/json"/>

</response>

Komponentenbasierte Software-Entwicklung

Page 164: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

473

@FormParam

<form action="http://vfl.de/mitglieder" method="post">

<p>

Vorname: <input type="text" name="vorname"><br>

Nachname: <input type="text" name="nachname"><br>

<input type="submit" value="Send">

</p>

</form>

@Path("/mitglieder")

@Consumes(Mediatype.APPLICATION_FORM_URLENCODED)

public class CustomerResource {

@POST

public void createCustomer(

@FormParam(“vorname") String vorname

, @FormParam(“nachname") String nachname) {

...

}

ermöglicht die Übernahme von Parametern einer POST-Anfrage eines HTML-Formulars

Komponentenbasierte Software-Entwicklung

Page 165: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

474

Response.Status (gibt evtl. passende Exceptions)public enum Status {

OK(200, "OK"), CREATED(201, "Created"),

ACCEPTED(202, "Accepted"),

NO_CONTENT(204, "No Content"),

MOVED_PERMANENTLY(301, "Moved Permanently"),

SEE_OTHER(303, "See Other"),

NOT_MODIFIED(304, "Not Modified"),

TEMPORARY_REDIRECT(307, "Temporary Redirect"),

BAD_REQUEST(400, "Bad Request"),

UNAUTHORIZED(401, "Unauthorized"),

FORBIDDEN(403, "Forbidden"),

NOT_FOUND(404, "Not Found"),

NOT_ACCEPTABLE(406, "Not Acceptable"),

CONFLICT(409, "Conflict"), GONE(410, "Gone"),

PRECONDITION_FAILED(412, "Precondition Failed"),

UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),

INTERNAL_SERVER_ERROR(500, "Internal Server Error"),

SERVICE_UNAVAILABLE(503, "Service Unavailable");

Komponentenbasierte Software-Entwicklung

Page 166: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

475

Weiterführend (1/2)

• asynchron@POST

@Asynchronous public void bearbeite(

@Suspended AsyncResponse ar, Daten daten)

• reguläre Ausdrücke in Path, @Path("{id : .+}")

komplexe Auswertungsregeln, was, wenn mehrere Möglichkeiten an Pfaden existieren

• HEAD: nimmt typischerweise erste GET und gibt statt Ergebnis nur Header und Response-Code zurück

• MIME-Types können sehr detailliert sein, generelltype/subtype;name=value;name=value...

@Consumes("application/xml;charset=utf-8")

Komponentenbasierte Software-Entwicklung

Page 167: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

476

Weiterführend (2/2)

• JAX-RS-Annotationen können auch nur in Interfaces ausgelagert werden

• Matrix-Parameter (Attribute) behandelbarhttp://beispiel.spieler.de/vfl;typ=Sturm/2015

• Nutzung von Header-Parametern @HeaderParampublic String get(@HeaderParam("Referrer") String

aufrufer) {

public String get(@Context HttpHeaders headers) {

• Cookie-Nutzung public String get(@CookieParam(“minr") int minr)

• genauere Analyse vom ResponseBuilder.status(.)

• Einbindung von Bean Validation

• …

Komponentenbasierte Software-Entwicklung

Page 168: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

477

Literatur

• (Standard-Links sind im Text)

• [Bur14] B. Burke, RESTful Java with JAX-RS 2.0, O‘Reilly, Sebastopol (CA), USA, 2014

• http://www.oracle.com/technetwork/articles/java/jaxrs20-1929352.html

Komponentenbasierte Software-Entwicklung

Page 169: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

478Komponentenbasierte Software-Entwicklung

6. Advanced JSF

6.1 Templates und Komponenten

6.2 Nutzung von Ajax

6.3 Testen von Web-Applikationen - Selenium

6.4 JSF-Erweiterungen

Page 170: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

479Komponentenbasierte Software-Entwicklung

6.1 Templates und Komponenten

Facelets - Motivation

• entwickelt, um JSP als View Declaration Language zu ersetzen

• Template-Ansatz um Wiederverwendung zu ermöglichen und Redundanzen zu vermeiden

• ein Ziel: Zusammensetzung einer logischen Seite aus verschiedenen Dateien unter Nutzung von Parametern

• JSF-View in XHTML-Syntax [nutzen wir immer]

• Erweiterungsmöglichkeit mit tag-Libraries (vgl. JSTL für JSP)

– Anmerkung: Vermeiden Sie möglichst die Nutzung der JSTL

• MVC-Ansatz, kein Java-Code in XHTML möglich (und nötig)

Hinweis: Chrome ab und zu bemerkenswert langsam

Page 171: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

480Komponentenbasierte Software-Entwicklung

Erstes Template-Beispiel (1/5) - Template rahmen.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html"

xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<h:head>

<h:graphicImage library="bilder" name="boah.jpg" width="200"

height="40" alt="boah"/>

<title>

<ui:insert name="titel"/>

</title>

</h:head>

<h:body>

<h:form>

<ui:insert name="rumpf"/>

<br/> <br/>

<h:commandLink value="Zurück" action="#{bsp.zurueck}"/>

</h:form>

</h:body>

</html>

Page 172: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

481Komponentenbasierte Software-Entwicklung

Erstes Template-Beispiel (2/5) - Bean

@Named

@RequestScoped

public class Bsp {

public String getErgebnis(){

return "Du solltest Dich ändern";

}

public String bad(){

return "/analyse.xhtml";

}

public String good(){

return "/analyse.xhtml";

}

public String zurueck(){

return "/index.xhtml";

}

}

Page 173: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

482Komponentenbasierte Software-Entwicklung

Erstes Template-Beispiel (3/5) - index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html"

xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<h:body>

<ui:composition template="./templates/rahmen.xhtml">

<ui:define name="titel">

Wesenstest

</ui:define>

<ui:define name="rumpf">

<h:outputText value="Was bist Du?"/>

<br/>

<h:commandButton value="Bad Guy" action="#{bsp.bad}"/>

<h:commandButton value="Good Boy" action="#{bsp.good}"/>

</ui:define>

</ui:composition>

</h:body>

</html>

Page 174: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

483Komponentenbasierte Software-Entwicklung

Erstes Template-Beispiel (4/5) - analyse.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html"

xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<h:body>

<ui:composition template="./templates/rahmen.xhtml">

<ui:define name="titel">

Ergebnis

</ui:define>

<ui:define name="rumpf">

<h:outputText value="#{bsp.ergebnis}"/>

</ui:define>

</ui:composition>

</h:body>

</html>

Page 175: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

484Komponentenbasierte Software-Entwicklung

Erstes Template-Beispiel (5/5) - Nutzung

Page 176: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

485Komponentenbasierte Software-Entwicklung

Aufbau genauer analysiert

• in index.xhtml<h:body>

<ui:composition template="./templates/rahmen.xhtml">

• im Template wird <h:head> gesetzt

• generell werden mit ui:composition Kinder des Wurzelknotens UIViewRoot erzeugt

• soll umgebender Text und Struktur berücksichtigt werden, ist ui:decorate zu nutzen; immer bei mehreren Templates

• Beispiel: folgender Text nur bei ui:decorate sichtbar

<h:body>

<h:outputText value="Hallo"/>

<ui:decorate template="./templates/rahmen.xhtml">

Page 177: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

486Komponentenbasierte Software-Entwicklung

Nutzung von Parametern

• in rahmen.xhtml<h:commandLink value="Zurück" action="#{bsp.zurueck}"

rendered="#{!start}"/>

• in index.xhtml<ui:composition template="./templates/rahmen.xhtml">

<ui:param name="start" value="true"/>

<ui:define name="titel">

• in analyse.xhtml<ui:composition template="./templates/rahmen.xhtml">

<ui:param name="start" value="false"/>

• Parameter auch bei anderen Elementen nutzbar

Page 178: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

487Komponentenbasierte Software-Entwicklung

Nutzung von ui:include (1/2) - index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!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://xmlns.jcp.org/jsf/facelets">

<ui:include src="./templates/head.xhtml">

<ui:param name="titel" value="Hallodele"/>

</ui:include>

<ui:include src="./templates/body.xhtml">

<ui:param name="text" value="rischtisch"/>

<ui:param name="obj" value="#{bsp}"/>

</ui:include>

</html>

Page 179: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

488Komponentenbasierte Software-Entwicklung

Nutzung von ui:include (2/2) - head/body.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html">

<h:head>

<title> <h:outputText value="#{titel}"/> </title>

</h:head>

</html>

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html">

<h:body>

<h3> <h:outputText value="#{text}"/> </h3>

<h:outputText value="#{obj.ergebnis}"/>

</h:body>

</html>

Page 180: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

489

Nutzung von h:graphicImage

• Verwaltung von Hilfsdateien und Bildern im Ordner WEB-INF/resources

• Nutzung

<h:graphicImage library="bilder" name="boah.jpg"

width="200" height="40" alt="boah"/>

Komponentenbasierte Software-Entwicklung

Page 181: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

490Komponentenbasierte Software-Entwicklung

Nutzung von ui:debug

• Im Development- oder Debug-Modus erhält man durch Drücken von CTRL+SHIFT+d Komponentenbaum angezeigt<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<ui:debug/>

<ui:include src="./templates/head.xhtml">

Page 182: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

491Komponentenbasierte Software-Entwicklung

Entwicklung eigener Komponenten

• Möglichkeit Komponenten basierend auf anderen Komponenten in XHTML zu realisieren

• konfigurierbar über Interface (hier nur Mini-Beispiel)

• vor eigener Entwicklung nachdenken:

– Realisierung mit Templates oder/und include genauso gut?

– gibt es gewünschte Komponente schon? (z. B. nachschauen unter http://jsfcentral.com/)

– Reichen nicht Validatoren, Konvertierer und evtl. PhaseListener aus?

Page 183: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

492Komponentenbasierte Software-Entwicklung

Komponente (1/4) - Schnittstelle glossar.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html"

xmlns:f="http://xmlns.jcp.org/jsf/core"

xmlns:ui="http://xmlns.jcp.org/jsf/facelets"

xmlns:composite="http://xmlns.jcp.org/jsf/composite">

<!-- INTERFACE -->

<composite:interface>

<composite:attribute name="schlagwort" required="true"/>

<composite:attribute name="detail" required="true"/>

</composite:interface>

Page 184: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

493Komponentenbasierte Software-Entwicklung

Komponente (2/4) - Implementierung

<!-- IMPLEMENTATION -->

<composite:implementation>

<h:panelGrid columns="2" rules="cols" frame="box">

<h:outputLabel value="#{cc.attrs.schlagwort}"/>

<h:panelGroup>

<p>

<h:outputText value="#{cc.attrs.detail}"/>

</p>

<composite:insertChildren/>

</h:panelGroup>

</h:panelGrid>

</composite:implementation>

</html>

Page 185: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

494Komponentenbasierte Software-Entwicklung

Komponente (3/4) - Beispielnutzung index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html"

xmlns:bsp="http://xmlns.jcp.org/jsf/composite/beispiel">

<h:head>

<title>Glossar</title>

</h:head>

<h:body>

<bsp:glossar schlagwort="Adam"

detail="der, wo nich allein sein konnte"/>

<bsp:glossar schlagwort="Eva"

detail="die, wo den Apfel nich lassen konnte">

Wo ist Missing Link?

</bsp:glossar>

</h:body>

</html>

Page 186: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

495Komponentenbasierte Software-Entwicklung

Komponente (4/4) - Ausgabe, Projektstruktur

Ordner muss so heißen

Page 187: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

496

Return-Taste soll zur Datenübernahme führen <h:body>

<ui:remove>

Die zentralen Knoepfe der Web-Seiten muessen den Namen

"schicken" haben, damit sie angesprungen werden

</ui:remove>

<h:form id="main" style="font-family:Calibri"

onkeypress="if (event.keyCode === 13) {

document.getElementById('main:schicken')

.click();

return false;

}">

• Detailliertere Bedingung im if:if (event.keyCode === 13)

and (event.target.nodeName == 'INPUT')

and (event.target.getAttribute('type') == 'text') {

document.getElementById(‚main:lokal').click();

return false;

}Komponentenbasierte Software-

Entwicklung

Page 188: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

497Komponentenbasierte Software-Entwicklung

Ausblick: Komponentenmöglichkeiten

• Im Interface wesentlich mehr als nur einfache Parameter (Attribute) definierbar

• Attribute können Verknüpfungen zu Action-Methoden bzw. Event-Listenern enthalten method-signature="java.lang.String f()"

• Übergabe weiterer Funktionalität (Methoden) an Komponente möglich für Event-Listener, Konvertierer und Validatoren

<composite:actionSource>

<composite:valueHolder>

<composite:editableValueHolder>

• Funktionalität kann dann bei inneren Komponenten der Composite-Komponente genutzt werden

Page 189: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

498Komponentenbasierte Software-Entwicklung

6.2 Nutzung von Ajax

• Ajax = Asynchronous JavaScript and XML(HTTPRequest)

– klassische Webapplikation:

• Nutzer macht Eingaben

• Nutzer beendet Eingabe (Knopf, Link, <Return>-Taste)

• Informationen an Server, der wertet aus

• neu berechnete Seite wird Nutzer zur Verfügung gestellt

• interaktive Applikation (Jesse James Garret, 2004)

– Nutzer macht Eingaben

– Eingaben führen auch während der Eingabe zu Reaktionen

– Informationen werden zwischenzeitlich auf Server ausgewertet

– berechnete Teilergebnisse werden in aktuelle Seite eingeblendet

Page 190: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

499Komponentenbasierte Software-Entwicklung

Ajax-Beispiel (1/3) - Bean

@Named("user")

@SessionScoped

public class Nutzer implements Serializable{

private String name = "";

public String getName() {

return this.name;

}

public void setName(String name) {

this.name = name;

}

}

Page 191: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

500Komponentenbasierte Software-Entwicklung

Ajax-Beispiel (2/3) - index.xhtml mit f:ajax

<h:form>

<h:outputText value="Your name: " />

<h:inputText id="in" value="#{user.name}" >

<f:ajax render="greeting" event="keyup"/>

<f:validateLength minimum="0" maximum="10" />

</h:inputText>

<h:message for="in"/>

<br/>

<h:panelGroup id="greeting" >

<h:outputText value="Hello, "

rendered="#{not empty user.name}" />

<h:outputText value="x " rendered="#{empty user.name}" />

<h:outputText value="#{user.name}" />

<h:outputText value="!" rendered="#{not empty user.name}"/>

</h:panelGroup>

</h:form>

Page 192: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

501Komponentenbasierte Software-Entwicklung

Ajax-Beispiel (3/3) - Ausgabe

• Start

• Nutzer tippt, dann unmittelbare Aktion

• (so) keine direkte Validierung

• Nutzer drückt Return-Taste

Page 193: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

502Komponentenbasierte Software-Entwicklung

Granulare Nutzung von f:ajax

• f:ajax kann um Komponenten gelegt werden

• f:ajax kann in Komponenten ergänzt werden (z. B. h:commandButton)

• f:ajax kann in und um Komponenten genutzt werden, dann ist Effekt die Summe aller spezifizierten Effekte

• Mehrere f:ajax-Einträge für eine Komponente ergänzen sich generell

• render: IDs der Komponenten, die neu gerendert werden sollen (auch @this = dieses Element, @form = umgebende Form, @all = alle Elemente, @none = kein Element)

• execute: IDs der Komponenten, die vollständig JSF-Lebenszyklus durchlaufen sollen (auch ... s. o.)

Page 194: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

503

Garantierte Aktualisierung

• Nicht alle Elemente werden sofort aktualisiert, z. B. h:commandButton

• Standardtrick: Zu verändernde Komponenten in h:Panelgroup oder h:panelgrid einordnen

<h:inputText id="nutzername" value="#{steuerung.nutzer}" >

<f:ajax render="edit" event="keyup" listener="#{…}"/>

</h:inputText>

<h:panelGroup id="edit">

<h:commandButton id ="editButton" value="Editieren"

action="#{…}" rendered="#{!empty steuerung.nutzer}"/>

</h:panelGroup>

Komponentenbasierte Software-Entwicklung

Page 195: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

504

Texteingabe und Knopf über Ajax

<h:inputText id ="nutzer" size="12"

value ="#{vc.nutzereingabe}"

onkeypress ="return event.keyCode !== 13;"/>

<h:commandButton value ="anmelden" >

<f:ajax event ="click"

execute = "nutzer"

render = "@form"

listener = "#{vc.nutzerEingegeben}"/>

</h:commandButton>

Komponentenbasierte Software-Entwicklung

Variable im Controller Verhindere

„Enter“-Taste

wichtig, damit Feld validiert wird

zu aktualisieren (ab und zu Holzhammer notwendig)

Methode im Controller

Page 196: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

505Komponentenbasierte Software-Entwicklung

Interaktionsspielerei (1/4) - index.xhtml

<h:form>

<h:outputLabel id="be" value="#{control.beruehrt}">

<f:ajax event="mouseover" render="be pg"

listener="#{control.drueber}"/>

<f:ajax event="mouseout" render="be pg"

listener="#{control.weg}"/>

</h:outputLabel>

<h:panelGrid id="pg" columns="2">

<h:outputText value="drueber:"/>

<h:outputText value="#{control.dzahl}"/>

<h:outputText value="weg:"/>

<h:outputText value="#{control.wzahl}"/>

</h:panelGrid>

</h:form>

Page 197: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

506Komponentenbasierte Software-Entwicklung

Interaktionsspielerei (2/4) - Verwaltungsklasse

@Named

@SessionScoped

public class Control implements Serializable{

private String beruehrt = "beruehr mich";

private int dzahl;

private int wzahl;

public String getBeruehrt() {return beruehrt;}

public int getDzahl() {return dzahl;}

public int getWzahl() {return wzahl;}

public void drueber() {

beruehrt = "beruehr mich nicht";

dzahl++;

}

public void weg() {

beruehrt = "beruehr mich";

wzahl++;

}

}

Page 198: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

507Komponentenbasierte Software-Entwicklung

Interaktionsspielerei (3/4) – Ausgabe Firefox

Page 199: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

508

Interaktionsspielerei (4/4) – Ausgabe Chrome

• Zähler laufen bei Bewegung auf dem Text los, maximaler Unterschied: eins

Komponentenbasierte Software-Entwicklung

Page 200: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

509Komponentenbasierte Software-Entwicklung

<h: Komponenten> und Events (Ausschnitt)

body X X X X X X X X X X X X

commandButton X X X X X X X X X X X X X X

commandLink X X X X X X X X X X X X X

dataTable X X X X X X X X X X

inputText X X X X X X X X X X X X X X X

inputTextArea X X X X X X X X X X X X X X X

outputLabel X X X X X X X X X X X X

panelGrid X X X X X X X X X X

selectManyMenu X X X X X X X X X X X X X X X

selectOneRadio X X X X X X X X X X X X X X X

actio

n

blur

chan

ge

clic

k

dblc

lick

focu

s

keyd

own

keyp

ress

keyu

p

load

mou

sedo

wn

mou

sem

ove

mou

seou

t

mou

seov

er

mou

seup

sele

ct

unlo

ad

valu

eCha

nge

Page 201: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

510

Polling mit Primefaces (1/2)

<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://xmlns.jcp.org/jsf/html"

xmlns:p="http://primefaces.org/ui">

<h:head>

<title>Poller</title>

</h:head>

<h:body>

<h:form>

<h:outputText id="o1" value="#{zeit.datum}"/><br/>

<h:outputText id="o2" value="#{zeit.anzahl}"/>

<p:poll interval="3" update="o1,o2"/>

</h:form>

</h:body>

</html>

Komponentenbasierte Software-Entwicklung

Page 202: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

511

Polling mit Primefaces (2/2)

@Named

@SessionScoped

public class Zeit

implements Serializable{

private int anzahl;

public String getDatum() {

anzahl++;

return new Date().toString();

}

public int getAnzahl() {

return anzahl;

}

}

Komponentenbasierte Software-Entwicklung

Page 203: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

512Komponentenbasierte Software-Entwicklung

Einschub: JSF und CSS (1/3)

• CSS-Dateien nutzbar

• fast allen JSF-Elementen können Style-Klassen (genauer Style-Spezifikationen) und konkrete Styles zugeordnet werden

Page 204: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

513Komponentenbasierte Software-Entwicklung

JSF und CSS (2/3) – Ausschnitt aus Anwendung

<h:head>

<title>Modulübersicht</title>

<h:outputStylesheet library="css" name="stil.css"/>

</h:head>

<h:form id="f2">

<h:messages globalOnly="true" styleClass="infoClass"/>

<h:panelGrid rendered="#{!empty module.module}">

<h:dataTable value="#{module.module}" var="m"

styleClass="resultGrid" rowClasses="oddRow,evenRow">

<h:column >

<f:facet name="header">

<h:outputText value="Nummer" />

</f:facet>

...

Page 205: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

514Komponentenbasierte Software-Entwicklung

JSF und CSS (3/3) - Beispielausgabe

Page 206: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

515

6.3 Testen von Web-Applikationen - Selenium

• Web-Browser nutzen schwerpunktmäßig HTML zur Darstellung

• Capture & Replay-Werkzeuge, die hardgecoded Pixel und Klicks verarbeiten, eignen sich meist auch für diese Programme

• Einfaches Werkzeug für Web-Applikationen und Firefox ist Selenium IDE [hier nicht gezeigt] (http://seleniumhq.org/)

– erlaubt Capture & Replay von Nutzereingaben

– ermöglicht Tests von Elementen, Identifizierung über Idsaber auch Beschriftungen

– erlaubt den Export der aufgezeichneten Tests u. a. in JUnit (Variante: Browsersteuerung aus JUnit heraus [nächste Folien], ähnlich FEST)

– basiert auf JavaScript und Iframes

Komponentenbasierte Software-Entwicklung

Page 207: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

516

Hinweise zum Testen

• Erinnerung: White Box – Grey Box – Black Box

• Basisfunktionalität mit JUnit testen

• einige Funktionalität ohne Server testbar

• gibt einfache Server nur zur Testausführung

• Selenium WebDriver ermöglicht Test der (Web-)Oberfläche

• niemals alle Tests durch Oberflächentests ersetzen

• es gibt nie das ultimative Werkzeug; aber Familie von Werkzeugen hilft oft

• nur automatisieren, wenn sinnvoll

• Ziel: Continuous Integration

Komponentenbasierte Software-Entwicklung

Page 208: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

517

Selenium WebDriver

• Selenium steuert Browser von Java (C#, Python, Ruby) aus

• Installation als jar-Dateien

• flexible Möglichkeiten zum Finden von GUI-Komponenten

• ideal für Regressionstests, bei wenig sich ändernden GUIs

• in fast allen Unternehmen genutzt, die Web-Applikationen herstellen

• kontinuierliche Weiterentwicklung (nicht immer alles übertragbar, Selenium -> Selenium 2)

• Grundregel: nur automatisieren, was sinnvoll und machbar ist, Rest manuell

• http://docs.seleniumhq.org/docs/

Komponentenbasierte Software-Entwicklung

Page 209: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

518

Selenium WebDriver - Konfiguration

• unterstützt alle gängigen Browser

• bei neuen Browsern muss eventuell auf Aktualisierung von WebDriver gewartet werden

• Oft kleine zusätzliche Programme pro Browser benötigt

– Firefox: geckodriver (https://github.com/mozilla/geckodriver/releases) Proxy für Marionette

• über Nutzer-Profile nachdenken

• generell Browser-Version nutzen, der vor der genutzten Selenium-Version fertig war

• generell notwendig: eigene Testumgebung

• typisch: Testserver mit fester Konfiguration; nicht notwendigerweise neuestem Browser

Komponentenbasierte Software-Entwicklung

Page 210: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

519

Beispielprogramm (1/3)

• Spezifikation: Zu entwickeln ist eine Applikation mit der geheime Nachrichten an einen Server übergeben und dort wieder abgefragt werden können. Genauer gibt der Nutzer eine Nachricht zusammen mit zwei Codewörtern und der Anzahl, wie oft die Nachricht abgerufen werden kann, ein. Weiterhin kann ein Nutzer über die Eingabe zweier Codewörter an gespeicherte Nachrichten kommen. Ist die Codewortkombination nicht vorhanden, wird ein Standardtext ausgegeben.

• Realisierung: Glassfish, JSF (Nutzung des Application Scope)

Komponentenbasierte Software-Entwicklung

Page 211: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

520

Beispielprogramm (2/3)

Server starten

Applikation starten

http://localhost:8080/SecretSafe/

Komponentenbasierte Software-Entwicklung

vergebene Ids:

main:verfassen

main:lesen

Page 212: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

521

Beispielprogramm (3/3)Nachricht verfassen Nachricht lesen

Komponentenbasierte Software-Entwicklung

eingabe:c1

eingabe:c2

eingabe:geheim

eingabe:ab

eingabe:verschicken

abfrage:c1

abfrage:c2

abfrage:abfragen

antwort:Nachricht

Page 213: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

522

Einblick in Nutzungsmöglichkeiten (1/14)public class SafeMoeglichkeitenTest {

private WebDriver driver;

private int linie = 0; // nur Ausgabespielerei

@BeforeClass

public static void setUpOnce() {

System.setProperty("webdriver.gecko.driver"

, "F:\\Programme\\geckodriver\\geckodriver.exe");

}

@Before

public void setUp() {

DesiredCapabilities capabilities = DesiredCapabilities.firefox();

capabilities.setCapability("marionette", true);

driver = new FirefoxDriver(capabilities);

// driver = new HtmlUnitDriver();

// driver = new ChromeDriver();

// driver = new InternetExplorerDriver(ieCapabilities);

}

Komponentenbasierte Software-Entwicklung

Page 214: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

523

Einblick in Nutzungsmöglichkeiten (2/14)

• Klasse WebDriver als zentrale Steuerungsmöglichkeit

• Erzeugt neue Browser-Instanz

• Browser muss auf dem System installiert sein, nutzt keine weiteren Einstellungen des aktuellen Nutzers (leeres Profil)

• Proxy zur Verbindung benötigt, FireFox: geckodriver.exe

• werden kontinuierlich weiterentwickelt

• (früher reichte driver = new InternetExplorerDriver(); )

• bisheriges Angebot (unterschiedliche Qualität): HtmlUnitDriver(), FirefoxDriver(), InternetExplorerDriver(), ChromeDriver(),

• OperaDriver durch andere Entwickler, IPhoneDriver nur zusammen mit Apple-XCode-Umgebung, AndroidDriver mit Android-Entwicklungsunterstützung

• Hintergrund: Selenium lange Zeit nur mit Firefox nutzbar

Komponentenbasierte Software-Entwicklung

Page 215: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

524

Einblick in Nutzungsmöglichkeiten (3/14)

• Zentrale Hilfsklasse für GUI-Komponenten: WebElement• nur zur Veranschaulichung: Ausgabemöglichkeit

private void zeigeElemente(List<WebElement> liste){

System.out.println("----"+(++linie));

if (liste != null) {

for (WebElement w : liste) {

System.out.println(" " + w.getTagName()

+ "::" + w.getAttribute("type")

+ "::" + w.getAttribute("name")

+ "::" + w.getAttribute("value")

+ "::" + w.getText()

+ "::" + w.getLocation() + "::" +w.isEnabled());

}

}

}

Komponentenbasierte Software-Entwicklung

Page 216: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

525

Einblick in Nutzungsmöglichkeiten (4/14)

• Überblick über generierte HTML-Seite

• In Entwicklung sinnvolle Ids/Namen vergeben

• JSF: Ids eindeutig

• Zugriff auch ohne Ids machbar („drittes Input-Element“)Komponentenbasierte Software-

Entwicklung

Page 217: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

526

Einblick in Nutzungsmöglichkeiten (5/14)

@Test

public void testBeispielvarianten()

throws InterruptedException, IOException {

// Seite aufrufen

driver.get("http://localhost:8080/SecretSafe/");

List<WebElement> liste =

driver.findElements(By.tagName("input"));

zeigeElemente(liste);

----1

input::hidden::main::main::::(0, 0)::true

input::submit::main:verfassen::Nachricht verfassen::::(8, 129)::true

input::submit::main:lesen::Nachricht lesen::::(8, 153)::true

input::hidden::javax.faces.ViewState::2158484851038199978:-

1608245938470041174::::(0, 0)::true

Komponentenbasierte Software-Entwicklung

Page 218: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

527

Einblick in Nutzungsmöglichkeiten (6/14)

List<WebElement> inp = driver.findElements(

By.xpath("//input"));

zeigeElemente(inp);

----2

input::hidden::main::main::::(0, 0)::true

input::submit::main:verfassen::Nachricht verfassen::::(8, 129)::true

input::submit::main:lesen::Nachricht lesen::::(8, 153)::true

input::hidden::javax.faces.ViewState::2158484851038199978:-

1608245938470041174::::(0, 0)::true

Komponentenbasierte Software-Entwicklung

Page 219: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

528

Einblick in Nutzungsmöglichkeiten (7/14)

• Viele weitere LokalisierungsmöglichkeitenMethod Summary

static By className(java.lang.String className)

static By cssSelector(java.lang.String selector)

WebElement findElement(SearchContext context)

List<WebElement> findElements(SearchContext context)

static By id(java.lang.String id)

static By linkText(java.lang.String linkText)

static By name(java.lang.String name)

static By partialLinkText(java.lang.String linkText)

static By tagName(java.lang.String name)

static By xpath(java.lang.String xpathExpression)

Komponentenbasierte Software-Entwicklung

Page 220: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

529

Einblick in Nutzungsmöglichkeiten (8/14)

• Steuerungsmöglichkeiten mit submit(), click(), weiteren Eingabemöglichkeiten

WebElement element =

driver.findElement(By.name("main:verfassen"));

System.out.println(element.getTagName()

+ "::" + element.getAttribute("type")

+ "::" + element.getAttribute("name")

+ "::" + element.getAttribute("value"));

element.click();

input::submit::main:verfassen::Nachricht verfassen

Komponentenbasierte Software-Entwicklung

Page 221: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

530

Einblick in Nutzungsmöglichkeiten (9/14)(new WebDriverWait(driver, 10)).until(

new ExpectedCondition<WebElement>() {

@Override

public WebElement apply(WebDriver d) {

return d.findElement(By.id("eingabe"));

}

});

System.out.println(driver.findElement(By.tagName("body")).getText());

Codewort 1:

Codewort 2:

geheime Nachricht:

wie oft abrufbar:

Zur Startseite

// Hilfsvariable für folgende Berechnung

List<WebElement> labels =

driver.findElements(By.tagName("input"));

Komponentenbasierte Software-Entwicklung

Warten bis Element erscheint

Page 222: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

531

Einblick in Nutzungsmöglichkeiten (10/14)

• es besteht die Möglichkeit JavaScript direkt auszuführen

• Mächtige Möglichkeiten, z. B. um Skripte zu starten oder Seite zu analysieren

• hier mit Übergabe und Rückgabe

@SuppressWarnings("unchecked")

List<WebElement> inputs2 = (List<WebElement>)

((JavascriptExecutor)driver).executeScript(

"var lbls = arguments[0]; "

+ "var inputs = []; "

+ "for (var i=0; i < lbls.length; i++){"

+ " inputs.push(document.getElementById("

+ " lbls[i].getAttribute('name'))); "

+ "} "

+ "return inputs;„ , labels);

zeigeElemente(inputs2);

Komponentenbasierte Software-Entwicklung

Aufrufparameter

Parameter für Aufruf

Page 223: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

532

Einblick in Nutzungsmöglichkeiten (11/14)

• Ausgabe zur letzten Folie

----3form::null::eingabe::null::Codewort 1:

Codewort 2:

geheime Nachricht:

wie oft abrufbar:

Zur Startseite::(8, 109)::true

input::text::eingabe:c1::::::(92, 109)::true

input::text::eingabe:c2::::::(92, 131)::true

input::text::eingabe:geheim::::::(138, 153)::true

input::text::eingabe:ab::0::::(120, 175)::true

input::submit::eingabe:verschicken::Verschicken::::(8,

197)::true

Komponentenbasierte Software-Entwicklung

Page 224: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

533

Einblick in Nutzungsmöglichkeiten (12/14)Object[] werte = {"input", "text"};

@SuppressWarnings("unchecked")

List<WebElement> inputs3 = (List<WebElement>)

((JavascriptExecutor) driver).executeScript(

"var tmp = document.getElementsByTagName(arguments[0]); "

+ "var erg = []; "

+ "for (var i=0; i<tmp.length; i++){"

+ " if(tmp[i].type==arguments[1]){"

+ " erg.push(tmp[i])"

+ " }"

+ "}; "

+ "return erg;", werte);

input::text::eingabe:c1::::::(92, 109)::true

input::text::eingabe:c2::::::(92, 131)::true

input::text::eingabe:geheim::::::(138, 153)::true

input::text::eingabe:ab::0::::(120, 175)::true

Komponentenbasierte Software-Entwicklung

Page 225: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

534

Einblick in Nutzungsmöglichkeiten (13/14)

// Gibt Seitentitel auf Konsole aus

System.out.println("Titel der Seite ist: "

+ driver.getTitle());

// Bildschirmfoto

File screenshot = ((TakesScreenshot)driver)

.getScreenshotAs(OutputType.FILE);

// FileUtils aus org.apache,commons,io

// http://commons.apache.org/proper/commons-io/download_io.cgi

FileUtils.copyFile(screenshot,

new File("bild"+new Date().getTime()+".png"));

Assert.assertTrue(driver.getTitle().contains("Pssst"));

}

Komponentenbasierte Software-Entwicklung

Page 226: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

535

Einblick in Nutzungsmöglichkeiten (14/14)

• nach mehren Testläufen

Komponentenbasierte Software-Entwicklung

Page 227: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

536

Projektaufbau

• zentral benötigte Bibliotheken im Selenium-Download

Komponentenbasierte Software-Entwicklung

alle benötigt

benötigt (aktuelle

Variante)

Page 228: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

537

Weitere Funktionalität

• Wechsel zwischen Fenstern und zwischen Frames

• Möglichkeit vorwärts und zurück zu navigieren

• Nutzung von Cookies

• (Versuch der) Unterstützung von Drag und Drop

• Proxy-Nutzung

• Einstellung von Wartezeiten

• Warten auf das Erscheinen von HTML-Elementen (wichtig in Richtung AJAX und HTML5)

• Zusammenspiel mit Selenium IDE zur Testaufzeichnung

Komponentenbasierte Software-Entwicklung

Page 229: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

538

Achtung: Viele Einstiegsfallen

• generell gute Einarbeitungsmöglichkeit durch gute Dokumentation

• trotzdem viele kleine Fehlerquellen, die Entwicklungsprozess bremsen können

• Beispiel: Tests ziehen auf anderen Rechner um

• wichtiges Detail aus der Doku "The browser zoom level must be set to 100% so that the native mouse events can be set to the correct coordinates." (nicht erster Google-Treffer)

• teilweise weitere Browser-Einstellungen beachten

• Browser-Updates benötigen teilweise Selenium-Updates

• Fazit: Testrechner nie zu anderen Zwecken nutzen, Konfiguration sichern

Komponentenbasierte Software-Entwicklung

Page 230: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

539

Weitere Steuerungsvarianten

• Warten, bis Element vorhanden ist(new WebDriverWait(driver, 10)).until(

new ExpectedCondition<WebElement>(){

@Override

public WebElement apply(WebDriver d) {

return d.findElement( By.name("j_idt8:j_idt10"));

}});

• Steuerungsvariante mit JavaScriptWebElement but =

driver.findElement(By.name("j_idt8:j_idt10"));

((IJavaScriptExecutor)driver)

.executeScript("arguments[0].fireEvent('onclick');", but);

Komponentenbasierte Software-Entwicklung

Page 231: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

540

Test des Beispiels (1/7)

public class SecretSafeTest {

private WebDriver driver;

private static String text1;

private static String text2;

private File f = new File("C:\\Users\\x\\AppData\\"

+ "Roaming\\Mozilla\\Firefox\\Profiles\\zm12egmo.default");

private FirefoxProfile profile = new FirefoxProfile(f);

@BeforeClass

public static void setupClass() {

text1 = "" + Math.random(); // nicht ganz QS-sauber

text2 = "" + Math.random(); // zufaellige Texte

System.setProperty("webdriver.gecko.driver"

, "F:\\Programme\\geckodriver\\geckodriver.exe");

}

@Before

public void setUp() {

driver = new FirefoxDriver(profile);

}Komponentenbasierte Software-

Entwicklung

Page 232: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

541

Test des Beispiels (2/7)@After

public void tearDown() {

driver.quit(); // dauert, sonst nur am Ende aller Tests

}

// zur Erkennung, ob Seite bereits geladen ist

private void warteAufSeiteMitId(String id) {

(new WebDriverWait(driver, 10)).until(

new ExpectedCondition<WebElement>() {

@Override

public WebElement apply(WebDriver d) {

return d.findElement(By.id(id));

}

});

}

private void startSeite(){

driver.get("http://localhost:8080/SecretSafe");

}

Komponentenbasierte Software-Entwicklung

Page 233: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

542

Test des Beispiels (3/7)

private void eingabeSeite(){

startSeite();

warteAufSeiteMitId("main");

driver.findElement(By.name("main:verfassen")).click();

warteAufSeiteMitId("eingabe");

}

private void ausgabeSeite(){

startSeite();

warteAufSeiteMitId("main");

driver.findElement(By.name("main:lesen")).click();

warteAufSeiteMitId("abfrage");

}

private void feldFuellen(String name, String wert){

driver.findElement(By.name(name)).clear();

driver.findElement(By.name(name)).sendKeys(wert);

}

Komponentenbasierte Software-Entwicklung

Page 234: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

543

Test des Beispiels (4/7)private void textEingeben(String text1, String text2,

String geheim, int versuche){

eingabeSeite();

feldFuellen("eingabe:c1",text1);

feldFuellen("eingabe:c2",text2);

feldFuellen("eingabe:geheim",geheim);

feldFuellen("eingabe:ab",""+versuche);

driver.findElement(By.name("eingabe:verschicken")).click();

warteAufSeiteMitId("erfolg");

Assert.assertTrue(driver.findElement(By.tagName("body"))

.getText().contains("Eintrag erfolgreich"));

}

private void textEingeben(String geheim, int versuche){

textEingeben(this.text1, this.text2, geheim, versuche);

}

Komponentenbasierte Software-Entwicklung

Page 235: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

544

Test des Beispiels (5/7)

private void textErfolgreichSuchen(String text1,

String text2, String geheim){

ausgabeSeite();

feldFuellen("abfrage:c1",text1);

feldFuellen("abfrage:c2",text2);

driver.findElement(By.name("abfrage:abfragen")).click();

warteAufSeiteMitId("antwort");

Assert.assertTrue(driver.findElement(By.tagName("body"))

.getText().contains(geheim));

}

private void textErfolglosSuchen(String text1, String text2){

ausgabeSeite();

feldFuellen("abfrage:c1",text1);

feldFuellen("abfrage:c2",text2);

driver.findElement(By.name("abfrage:abfragen")).click();

warteAufSeiteMitId("antwort");

Assert.assertTrue(driver.findElement(By.tagName("body"))

.getText().contains("Treffen um 730 in KN2"));

}Komponentenbasierte Software-Entwicklung

Page 236: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

545

Test des Beispiels (6/7)private void textErfolgreichSuchen(String geheim){

textErfolgreichSuchen(text1, text2, geheim);

}

private void textErfolglosSuchen(){

textErfolglosSuchen(text1, text2);

}

@Test

public void testErfolglos(){

textErfolglosSuchen();

}

@Test

public void testEintragenUndLesen(){

textEingeben("TextText", 3);

textErfolgreichSuchen("TextText");

textErfolgreichSuchen("TextText");

textErfolgreichSuchen("TextText");

textErfolglosSuchen();

}Komponentenbasierte Software-

Entwicklung

Page 237: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

546

Test des Beispiels (7/7)

@Test

public void testLinkLesen(){

ausgabeSeite();

driver.findElement(By.linkText("Zur Startseite")).click();

warteAufSeiteMitId("main");

Assert.assertTrue(driver.findElement(By.tagName("body"))

.getText().contains("Was wollen Sie machen?"));

}

@Test

public void testLinkSchreiben(){

eingabeSeite();

driver.findElement(By.linkText("Zur Startseite")).click();

warteAufSeiteMitId("main");

Assert.assertTrue(driver.findElement(By.tagName("body"))

.getText().contains("Was wollen Sie machen?"));

}

// weitere Tests sinnvoll

}Komponentenbasierte Software-Entwicklung

Page 238: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

547

Testarchitektur

• Tests müssen für Änderbarkeit konzipiert werden

• häufig: viele Tests für eine konkrete Version geschrieben, nach leichten Änderungen der zu testenden Software werden Tests als unwartbar weggelegt

• Problem: ähnlich wie Software-Architektur wird Test-Architektur benötigt

• ein Ansatz: jeweils eigene Steuerungsklasse für eine Web-Seite, Tests arbeiten nur auf diesem Abstraktionslevel

• kleine Änderungen führen zu kleinen Änderungen in der Steuerungsklasse und keinen Änderungen bei deren Nutzern

• durch Abstraktion muss nicht jeder Tester Selenium können

• -> Tests müssen von qualifizierten Software-Entwicklern geschrieben werden

Komponentenbasierte Software-Entwicklung

Page 239: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

548Komponentenbasierte Software-Entwicklung

Design-Tests

• Browser stellen identische Inhalte leicht verändert da

• technisch überflüssig, aber wichtig für den Zeitgeist: modische Design-Anpassungen

• Für IT-Profi: Sisyphos-Arbeit; Test mit unterschiedlichen Browsern

• Direkte Hilfsmittel:

– Lunascape: ein Browser, bei dem man zwischen drei Maschinen umschalten kann IE (Trident)+Firefox (Gecko)+Chrome, Safari (Webkit)

– Windows: USB-portable Browser ohne Installationsnotwendigkeit (verändern keine Einstellungen): Firefox, Chrome, Opera, …

• evtl. auch Capture & Replay mit Selenium zum inhaltlichen Test

Page 240: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

549Komponentenbasierte Software-Entwicklung

6.4 JSF-Erweiterungen

• graphische Möglichkeiten in JSF recht schlicht (wesentlich besser als gezeigt!), Erweiterungsbibliotheken sinnvoll

• wesentliche frei nutzbare Komponentenframeworks:– RichFaces: http://www.jboss.org/richfaces– Primefaces: http://www.primefaces.org/

• alternative JSF-Implementierung (Standard: Mojarra):– Apache MyFaces: http://myfaces.apache.org/

• kritisch: Frameworks nur teilweise kompatibel, gilt auch für Framework mit Implementierung

• kritisch: in Details teilweise deutliche Darstellungsunterschiede in verschiedenen Browsern

• Hinweis: hier nur Ideen und notwendige Konfiguration• NetBeans bietet Nachlademöglichkeit; hier nicht genutzt um

einfacher IDE wechseln zu können

Page 241: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

550Komponentenbasierte Software-Entwicklung

Nutzung von PrimeFaces

• unterstützt JSF 2, Projekt ab November 2008

• Dokumentation war mal kostenpflichtig

• aktuell mit Support (Elite Downloads) und ohne (Community Downloads)

• Installation durch Einbinden einer einzelnen jar-Datei

• sehr viele Gestaltungsmöglichkeiten, mit Showcases gut dokumentiert

• Elemente haben oft sehr viele Parameter für Konfigurationsmöglichkeiten

• Ansatz: zu GUI-Element gehört Java-Objekt mit Konfigurationsmöglichkeiten in Java (set)

Page 242: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

551Komponentenbasierte Software-Entwicklung

Beispiel: Editorspielerei (1/4) - Managed Bean

@Named

@SessionScoped

public class Text implements Serializable {

private String inhalt;

public String getInhalt() {

return inhalt;

}

public void setInhalt(String inhalt) {

this.inhalt = inhalt;

}

}

Page 243: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

552Komponentenbasierte Software-Entwicklung

Beispiel: Editorspielerei (2/4) - index.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://xmlns.jcp.org/jsf/html"

xmlns:p="http://primefaces.org/ui">

<h:head>

<title>Editor</title>

</h:head>

<h:body>

<h:form >

<p:editor id="ed" width="600px" height="120px"

value="#{text.inhalt}" widgetVar="editor"/>

<p:commandButton update="o1,o2" async="true"

value="p Uebernehmen" onclick="editor.saveHTML();"/><br/>

<h:commandButton value="h Uebernehmen"/><br/>

<h:outputText id="o1" escape="true"

value="Inhalt: #{text.inhalt}"/><br/>

<h:outputText id="o2" escape="false"

value="Inhalt: #{text.inhalt}"/>

</h:form>

</h:body>

</html>

Page 244: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

553Komponentenbasierte Software-Entwicklung

Beispiel: Editorspielerei (3/4) - h: (Seite lädt neu)

Page 245: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

554Komponentenbasierte Software-Entwicklung

Beispiel: Editorspielerei (4/4) - p: (Aktualisierung)

Page 246: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

555Komponentenbasierte Software-Entwicklung

Anmerkungen zum Beispiel

• Normalerweise unterstützt p:commandButton Ajax direkt (nur bei p:editor Problem, deshalb Workaround mit widgetVar)

• <h:head> immer benötigt

• Generell: Genaue Analyse der oft sehr vielen Attribute einer Komponente notwendig

• Mischung von h: und p: oft (nicht immer) möglich

• Man muss mit Eigenarten der Komponenten leben (bei Großprojekten und Auswahlentscheidungen schwierig)

• detaillierte Dokumentation als PDF-Download http://www.primefaces.org/documentation

Page 247: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

556

Versionsänderung - Beispiel

• Versionswechsel 2.0.2 zu 2.2.1 führt zu anderer Darstellung• Ungleichheit p: und h: korrigiert• andere Attribute statt height="120px" nun height="120"

Komponentenbasierte Software-Entwicklung

Page 248: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

557Komponentenbasierte Software-Entwicklung

JSF - es geht noch weiter

• JSF Expression Language– einfacher Zugriff auf Maps, die Umgebungsdaten, wie

param, requests, cookies und initParam haben– Nutzung von flash-Variable als Zwischenspeicher

• Erweiterung der Expression Language • Möglichkeit GET zu nutzen (und damit Bookmarks)

– <h:button> und <h:link>• JSF hat klare Regeln wie Ressourcen verwaltet werden

(Bilder, Templates, ...) • integrierte, nutzbare JavaScript-API• Viele weitere JavaScript-Möglichkeiten (u. a. h:outputScript)• weitere Möglichkeiten des Event-Handlings, z. B. eigene

Klasse reagiert auf Event (z. B. Phasenwechsel)• Ergänzung/Erweiterung des Exception Handlings• Lokalisierung, Mehrsprachlichkeit

Page 249: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

558

7. Contexts and Dependency Injection

• klassisch Dependency Injection

• was kennen wir bereits

• CDI im Detail

– Aktivierung

– Qualifier

– Event Handling

– Objekte injizieren

– Produzenten

– Alternativen

– Interception

• Fazit

Komponentenbasierte Software-Entwicklung

Page 250: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

559

Ausblick auf weitere Themen

Komponentenbasierte Software-Entwicklung

Browser

Datenbank

JPA

EJBBean

Validation

Scope

JSFRESTful

WebService

Web Sockets

1

CDI

2

3

Page 251: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

560

Dependency Injection klassisch (1/2)

woher kommen Objekte für Exemplarvariablen?

• Variante 1: Werte werden als Parameter übergeben, aus denen Objekte gebaut werden (Objekt baut sich benötigte Objekte selber)

• Variante 2: Objekte werden als Referenzen übergeben

– Optimierung: Typen der Objektvariablen sind Interfaces; so konkrete Objekte leicht austauschbar

• Variante 2 heißt Dependency Injection mit get- und set-Methoden oder über Konstruktoren

Komponentenbasierte Software-Entwicklung

Page 252: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

561

Dependency Injection klassisch (2/2)

Nutzer nutzer = new Nutzer(new Inter1RealA(42)

, new Inter2RealC(43)

, new Inter3RealD("Hallo"));

eng verknüpft mit Factory Pattern

Komponentenbasierte Software-Entwicklung

Page 253: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

562

JSF nutzt bereits Dependency Injection

@Named

@SessionScoped

public class SprintController implements Serializable

@Inject

PersistenzService pers;

• @Named: Objekt steht und festen Namen zur Oberflächengestaltung zur Verfügung

• @SessionScoped: Objekt steht für die gesamte Session (auch allen anderen Objekten) zur Verfügung (Context)

• @Inject: „Umgebung gib (injiziere) mir ein zum Typen passendes Objekt“

• @PostConstruct: garantiert nach Erzeugung, vor Nutzung

• Hinweis: Annotationen stammen aus dem CDI-Paket; es gibt sehr ähnliche in JSF-Paketen (JSF ohne CDI machbar)

Komponentenbasierte Software-Entwicklung

Page 254: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

563

Ziele CDI

• Entkopplung von Objekten voneinander

– @Inject bestes Beispiel, es wird nur ein passendes Objekt „irgendwoher“ benötigt; dies besorgt CDI-Realisierung

• Vereinfachte Objekt-Kommunikation

– Beispiel: Informationen abonnieren (bekannt als PublishSubscribe oder Observer Observable)

• Vereinfachung von querschnittlich in mehreren Objekten benötigter Funktionalität

– Beispiel: Logging

• Hinzufügen von Funktionalität zu bestimmten Ereignissen ohne betroffene Methoden zu verändern

– Beispiel: Konsistenzprüfung, Benachrichtigung (Aspektorientierung)

Komponentenbasierte Software-Entwicklung

Page 255: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

564

Informationsquellen

• CDI 1.1 gehört zu JEE 7

• JSR 299: Contexts and Dependency Injection for the JavaTM EE platform, https://jcp.org/en/jsr/detail?id=299

• JSR 346: Contexts and Dependency Injection for JavaTM EE 1.1, https://jcp.org/en/jsr/detail?id=346

• JSR 365: Contexts and Dependency Injection for JavaTM 2.0 https://jcp.org/en/jsr/detail?id=365

• Spezifikation http://www.cdi-spec.org/

• Referenzimplementierung Weld 2.0 (JBoss)

• gute Einführung: http://docs.jboss.org/weld/reference/latest/en-US/html/intro.html

Komponentenbasierte Software-Entwicklung

Page 256: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

565

NetBeans: kein Deploy on Save

gerade bei CDI ist ein vollständiges Clean & Build mit Deployfast immer sinnvoll, da Server sonst Probleme z. B. mit noch laufenden Sessions hat (Haken wegnehmen)

Komponentenbasierte Software-Entwicklung

Page 257: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

566

Aktivierung

• explizit mit beans.xml in WEB-INF –Ordner; für reine EJB-Module oder jar-Dateien im Ordner META-INF<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"

version="1.1" bean-discovery-mode="all">

</beans>

• implizit, ohne beans.xml oder mit und bean-discovery-mode="annotated", werden nur Beans mit Scope gefunden; typischerweise @Dependent für im Scope des Nutzers

• in beans.xml können (und müssen teilweise) weitere Eigenschaften spezifiziert werden

Komponentenbasierte Software-Entwicklung

Page 258: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

567

zentrales Hilfsmittel Qualifier

• Qualifier sind einfache Annotationen, mit denen gewünschte bzw. geforderte Eigenschaften spezifiziert werden können

• Normale neue Annotation mit Zusatzannotation @Qualifier...

import javax.inject.Qualifier;

@Qualifier

@Target({ElementType.TYPE, ElementType.METHOD,

ElementType.PARAMETER, ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)

public @interface Info{}

• folgende Folien: Qualifier nur erwähnt, haben dann die hier angegebene Form

Komponentenbasierte Software-Entwicklung

Page 259: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

568

Event-Model (Observer – Observable)

• auch Publish-Subscribe

• Observer sagt Bescheid, dass er vom Observable informiert werden möchte

• Observable schickt Informationen an alle Abonnenten

• Beispielaufgabe (Balkon): Informiere alle Interessierten, dass gerade ein Objekt persistiert werden soll

Komponentenbasierte Software-Entwicklung

Page 260: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

569

Event Model Übersicht (müssen nicht EJBs sein)

Komponentenbasierte Software-Entwicklung

class MeinEvent

beliebige POJO-Klasse

@Stateless

public class PersistenceService {

@Inject @Info Event<MeinEvent> event

MeinEvent me = …

event.fire(me);

Observable

@Qualifier

public @interface Info{}

Qualifier

@Stateless

public class EventConsumer {

public void empfangeMeinEvent(

@Observes @Info MeinEvent event)

{…

Observer

Page 261: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

570

Definition des Event-Objekts

• POJO mit Inhalten, die übertragen werden sollenpackage cdi.eventing;

public class MeinEvent { // POJO

private Object obj;

public MeinEvent(){

}

public Object getObj() {

return obj;

}

public void setObj(Object obj) {

this.obj = obj;

}

}

Komponentenbasierte Software-Entwicklung

Page 262: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

571

Observable – Benachrichtigen (Ausschnitt)

@Stateless

public class Persistence {

@Inject @Info Event<MeinEvent> event;

@Inject

private EntityManager em;

public void persist(MitarbeiterDTO mi) {

Mitarbeiter m = mi.toMitarbeiter();

MeinEvent e = new MeinEvent();

e.setObj(m);

event.fire(e);

this.em.persist(m);

event.fire(e);

}

Komponentenbasierte Software-Entwicklung

Page 263: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

572

Observer 1

• Durch Annotation @Info können verschiedenartige Events unterschieden werden

• beteiligte Objekte sind EJBs oder haben einen Scope (oder übernehmen Scope des nutzenden Objekts)@Stateless

public class EventConsumer {

public void empfangeMeinEvent(

@Observes @Info MeinEvent event) {

System.out.println("obs1 " + event.getObj());

}

}

// wenn Konsument nicht existiert, wird er erzeugt!

// nicht gewünscht: @Observes(notifyObserver=Reception.IF_EXISTS)

Komponentenbasierte Software-Entwicklung

Page 264: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

573

Observer 2

@Stateless

public class EventConsumer2 {

// Methode zeigt Machbarkeit des Ansatzes, ob dies hier

// sinnvoll, ist fraglich

public void empfangeMeinEvent(

@Observes @Info MeinEvent event) {

System.out.println("obs2 " + event.getObj().getClass());

if (event.getObj() instanceof Mitarbeiter){

Mitarbeiter m = (Mitarbeiter)event.getObj();

m.setVorname(m.getVorname() + " " + m.getNachname());

}

}

}

Komponentenbasierte Software-Entwicklung

Page 265: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

574

Konkretisierung injizierter Objekte

• bisher war immer eindeutig, welches Objekt bei @Inject genutzt wird

• häufig wird aber eine bestimmte Variante eines Objekts benötigt

• Ausgangspunkt: gibt Interface (oder abstrakte Klasse) mit mehreren Realisierungen

• der konkret gewünschte Objekttyp wird dann durch @Inject und die zusätzliche Angabe von Qualifiern festgelegt

• Beispiel: es gibt zwei verschiedene Ausgabemöglichkeiten, unterschieden durch Qualifier @LogQualifier und @SystemQualifier

Komponentenbasierte Software-Entwicklung

Page 266: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

575

Konkretisierung Übersicht

Komponentenbasierte Software-Entwicklung

interface Ausgabe {…

Angabe gewünschter Variante

@LogQualifier

public class AusgabeLog implements Ausgabe {…

@Qualifier

public @interface SystemQualifier{}

Qualifier

@Stateless

public class EventConsumer {

@Inject @LogQualifier Ausgabe aus;

@Qualifier

public @interface LogQualifier{}

Qualifier

@SystemQualifier

public class AusgabeSys implements Ausgabe {…

Interface

Realisierung

Realisierung

Page 267: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

576

Beispiel (1/3): Realisierungen 1/2

public interface Ausgabe {

public void ausgeben(String s);

}

@SystemQualifier

public class AusgabeSystem implements Ausgabe{

@Override

public void ausgeben(String s) {

System.out.println("System " + s);

}

}

Komponentenbasierte Software-Entwicklung

Page 268: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

577

Beispiel (2/3): Realisierungen 2/2

@LogQualifier

public class AusgabeLog implements Ausgabe{

private final static Logger LOGGER = Logger

.getLogger(AusgabeLog.class.getSimpleName());

@Override

public void ausgeben(String s) {

LOGGER.log(Level.INFO, "AusgabeLog: {0}", s);

}

}

Komponentenbasierte Software-Entwicklung

Page 269: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

578

Beispiel (3/3): Auswahl der Realisierung

@Stateless

public class EventConsumerAusgabe {

@Inject @LogQualifier Ausgabe aus;

public void empfangeMeinEvent(

@Observes @Info MeinEvent event) {

//System.out.println("obs1 " + event.getObj());

aus.ausgeben("obsaus1 " + event.getObj());

}

}

• ein zentrales Logging kann man mit CDI besser durch Interceptors realisieren

• es können auch mehrere Qualifier angegeben werdenKomponentenbasierte Software-

Entwicklung

Page 270: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

579

Auswahlregeln

• Wenn Bean keinen Qualifier hat, wird er automatisch als @Default gesetzt (kann man auch hinschreiben)

• ohne benötigten Qualifier kann @Any genutzt werden

• Klassen haben ohne Scope-Angabe den Scope @Dependent, der sich dem Scope des nutzenden Objekts anpasst

Komponentenbasierte Software-Entwicklung

Page 271: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

580

Produzenten

• bisher wurde bei @Inject nach passenden Klassen gesucht und ein Objekt per Default-Konstruktor erzeugt

• Objekt-Erzeugung kann aber auch durch mit @Producesannotierte Konstruktoren, Methoden (Rückgabe-Objekt) oder direkt Exemplarvariablen erfolgen

• Konkretisierung des erzeugten Objekts wieder durch Qualifier (@Starttext, @Meldung im nächsten Beispiel)

• Beispiel zeigt kritische „Wiederverwendung“ von Qualifier

• javax.enterprise.inject.Produces nutzen

Komponentenbasierte Software-Entwicklung

Page 272: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

581

Statische Produzenten Übersicht (public vergessen)

Komponentenbasierte Software-Entwicklung

Produktions-varianten

@Qualifier

@interface Info{}

Qualifier

class Produzent {

@Produces @Meldung

private String meldung;

@Produces @Starttext

public String getLogtext() {…

@Produces @Starttext @Info

public String getLogtext2() {…

@Qualifier

@interface Meldung{}

Qualifier

class AusgabeLog {…

@Inject @Starttext @Info

private String start;

@Inject @Meldung

private String text;

Beispielnutzungen

@Qualifier

@interface Starttext{}

Qualifier

Page 273: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

582

Beispiel (1/2): Produzenten-Klasse

public class Produzent implements Serializable {

private String logtext = "logtext";

@Produces @Meldung

private String meldung;

public Produzent() { this.meldung = "Hai";}

@Produces @Starttext

public String getLogtext() {

return "prod1 " + this.logtext;

}

@Produces @Starttext @Info

public String getLogtext2() {

System.out.println("getLogtext2");

return "prod2 " + this.logtext;

}

}

Komponentenbasierte Software-Entwicklung

Page 274: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

583

Beispiel (2/2): Nutzer der Produzenten

@LogQualifier2

public class AusgabeLog2 implements Ausgabe{

private final static Logger LOGGER = Logger

.getLogger(AusgabeLog.class.getSimpleName());

@Inject @Starttext @Info private String start;

@Inject @Meldung private String text;

@Override

public void ausgeben(String s) {

LOGGER.log(Level.INFO, "AusgabeLog2: {0}", s);

LOGGER.log(Level.INFO, "prodnutzer {0} {1}: {2}"

, new Object[]{this.text, this.start, s});

}

}Komponentenbasierte Software-Entwicklung

Page 275: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

584

Dynamische Produzenten Übersicht

Komponentenbasierte Software-Entwicklung

Produktions-methode

Qualifier

public class Produzent{

@Produces @Aktuell

public String mach(){…

@Qualifier

public @interface Aktuell{}

public class AusgabeLog {

@Inject @Aktuell

Instance<String> datum;

public void ausgeben(…) {

datum.get()});

Beispielnutzung

Page 276: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

585

Dynamische Produktion (1/2) : Erzeugung

• wieder Produzenten-Methode mit üblichen Qualifier (also nichts Neues hier)

public class Produzent implements Serializable {

@Produces @Aktuell

public String mach(){

return "dynprod " + new Date().toString();

}

...

Komponentenbasierte Software-Entwicklung

Page 277: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

586

Dynamische Produktion (2/2): Aufruf

@LogQualifier3

public class AusgabeLog3 implements Ausgabe{

@Inject @Aktuell Instance<String> datum;

...

@Override

public void ausgeben(String s) {

LOGGER.log(Level.INFO, "AusgabeLog3: {0} - {1}"

, new Object[]{s, datum.get()});

// LOGGER.log(Level.INFO, "{0} {1}: {2}"

// , new Object[]{this.text, this.start, s});

}

Komponentenbasierte Software-Entwicklung

Page 278: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

587

Inject-Varianten

• statt @Inject an Exemplarvariablen zu schreiben, ist dies auch möglich:@Inject

public Konstruktor(Typ ichWerdeInjected){ …

@Inject

public void methode(Typ ichWerdeInjected){ …

• natürlich wieder Qualifier nutzbar

• weiterführend: mit @Typed an Klasse einschränken, für welche Klassen und Interfaces diese eingesetzt werden kann

Komponentenbasierte Software-Entwicklung

Page 279: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

588

Alternativen

• über Qualifier können passende Klassen genau ausgewählt werden

• z. B. zu Testzwecken, sollte diese Auswahl aber einfach änderbar sein

– hierzu wird Klasse mit @Alternative markiert

– UND muss in der beans.xml als ausgewählte Alternative angegeben werden

• durch Änderung der beans.xml sehr einfach Klassenauswahl auf Testphase oder länderspezifische Auswahlen änderbar

• mehrere Alternativen bei mehreren genutzten jars angebbar, dann Auswahl so steuerbar:

@Priority(Interceptor.Priority.APPLICATION + 10)

komplexes, sehr flexibles Auswahlsystem, wann welche Klasse genutzt wird (@Specialization)

Komponentenbasierte Software-Entwicklung

Page 280: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

589

Nutzung der Alternative (1/2): weitere Klasse

import cdi.qualifier.ausgabe.LogQualifier;

import javax.enterprise.inject.Alternative;

@Alternative

@LogQualifier

public class AusgabeLogMock implements Ausgabe{

@Override

public void ausgeben(String s) {

System.out.println("LogMock: " + s );

}

}

Komponentenbasierte Software-Entwicklung

Page 281: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

590

Nutzung der Alternative (2/2): beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"

bean-discovery-mode="all">

<alternatives>

<class>cdi.AusgabeLogMock</class>

</alternatives>

</beans>

Komponentenbasierte Software-Entwicklung

Page 282: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

591

Interceptor Übersicht

Komponentenbasierte Software-Entwicklung

unterbreche alle Methoden von

Interceptor-Benennung

@Stateless

@InterceptQualifier

public class BspKlasse {

public void meth1(…) {…

public void meth2(…) {…

@Inherited

@InterceptorBinding

public @interface InterceptQualifier{}

@InterceptQualifier

@Interceptor

public class MeinInterceptor {

@AroundInvoke

public Object logCall(

InvocationContext ctx)

throws Exception { …

Method meth = ctx.getMethod();

for (Object o: ctx.getParameters())

return ctx.proceed();

} …

bei Unterbrechung zu nutzen

<interceptors>

<class>cdi.MeinInterceptor

</class>

</interceptors>

Page 283: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

592

Interception

• Ansatz: sich in verschiedenen Methoden wiederholende Aufgaben zentral auslagern (Aspekt-Orientierung)

• (einziger) Klassiker: Logging (evtl. Sicherheit)

• Ansatz: Werden markierte Methoden oder Methoden in markierten Klassen ausgeführt, wird zunächst zum Interceptor gehörende Methode durchgeführt

• Interceptor kann auf Methode und Parameter zugreifen

• Interceptor muss Methodenausführung starten (proceed())

• Interceptor muss über beans.xml eingeschaltet werden (nur in diesem Archiv aktiv) oder @Priority-Annotation besitzen

• Interceptor benötigt eigene Art von Qualifier

• folgendes Beispiel zeigt ungewöhnliche Nutzung (auch Verstoß, dass möglichst wenig beobachtet werden soll)

Komponentenbasierte Software-Entwicklung

Page 284: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

593

Nutzung von Interception (1/5): Annotation

import java.lang.annotation.ElementType;

import java.lang.annotation.Inherited;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

import javax.interceptor.InterceptorBinding;

//@Qualifier

@Inherited

@InterceptorBinding

@Target({ElementType.TYPE, ElementType.METHOD })

@Retention(RetentionPolicy.RUNTIME)

public @interface InterceptQualifier{}

Komponentenbasierte Software-Entwicklung

Page 285: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

594

Nutzung von Interception (2/5): Bereich festlegen

• Hier werden alle Methoden der Klasse beobachtet, man kann die Annotation auch nur für einzelne Methoden nutzen

@Stateless

@InterceptQualifier

public class EventConsumer3 {

public void empfangeMeinEvent(

@Observes @Info MeinEvent event) {

System.out.println("obs3 " + event.getObj().getClass());

if (event.getObj() instanceof Mitarbeiter) {

Mitarbeiter m = (Mitarbeiter) event.getObj();

m.setVorname(m.getVorname() + " X");

}

}

}

Komponentenbasierte Software-Entwicklung

Page 286: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

595

Nutzung von Interception (3/5): Realisierung 1/2

@InterceptQualifier

@Interceptor

public class MeinInterceptor {

@AroundInvoke // gibt auch @AroundConstruct, @PostConstruct

public Object logCall(InvocationContext context)

throws Exception {

Method meth = context.getMethod();

System.out.println("inter Methode: " + meth);

/*

for (Object o : context.getParameters()) {

System.out.print(o + " ");

}

*/Komponentenbasierte Software-

Entwicklung

Page 287: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

596

Nutzung von Interception (4/5): Realisierung 2/2

MeinEvent event = (MeinEvent) context.getParameters()[0];

if (event.getObj() instanceof Mitarbeiter) {

Mitarbeiter m = (Mitarbeiter) event.getObj();

if (event.getObj() instanceof Mitarbeiter) {

Mitarbeiter m = (Mitarbeiter) event.getObj();

m.setNachname(m.getNachname() + "Y");

}

return context.proceed(); // wichtig irgendwann aufrufen

}

}

Komponentenbasierte Software-Entwicklung

Page 288: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

597

Nutzung von Interception (5/5): beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"

bean-discovery-mode="all">

<interceptors>

<class>cdi.MeinInterceptor</class>

</interceptors>

</beans>

Komponentenbasierte Software-Entwicklung

Page 289: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

598

Decorator (1/2): Erinnerung Pattern

Komponentenbasierte Software-Entwicklung

• ergänze neue Klasse (Decorator) die das Interface realisiert und ein Objekt der Klasse als Exemplarvariable hält

• Idee: delegiere Aufrufe an diese Exemplarvariable und ergänze drum herum neue Funktionalität

• flexibler: Exemplarvariable nutzt Interface-Typ

Page 290: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

599

Decorator (2/2): Umsetzung in CDI

@Decorator

public class AusgabeDecorator implements Ausgabe{

@Inject @Delegate @Any Ausgabe aus;

@Override

public void ausgeben(String s) {

System.out.println("Starte Dekoration: " + s);

this.aus.ausgeben(s);// nutze dekoriertes Objekt

System.out.println("Ende Dekoration");

}

}

Komponentenbasierte Software-Entwicklung

Page 291: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

600

Stereotype

• mit CDI können große Mengen von Annotationen entstehen

• häufiger haben ähnliche Klassen die gleichen Annotationen

• diese können als neue Annotation zusammengefasst werden

@RequestScoped

@Named

@MeineAnnotation

@Stereotype

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface Aktion {}

• Klassen können auch mit mehreren Stereotypes (auch überlappend) annotiert werden

• Beispiel: @Model vereint @Named und @RequestScopedKomponentenbasierte Software-

Entwicklung

Page 292: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

601

Weiterführende Themen

• CDI auch zu eigener Transaktionssteuerung nutzbar

Meinung: wenn JEE und EJB genutzt werden, spricht wenig für diesen Ansatz (Transaktion über mehrere Methoden)

interessant:

[Mül 14] B. Müller, JSF und JPA im Tandem, Teil 1, in: Javamagazin, 5/2014, Seiten 98-102, Software & Support Media GmbH, Frankfurt a. M. , 2014

• Auf Spezifikationsseite kann man sich über neue Versionen informieren

Komponentenbasierte Software-Entwicklung

Page 293: 4.5 JSF mit EJB und JPA - home.edvsz.fh-osnabrueck.dehome.edvsz.fh-osnabrueck.de/skleuker/WS18_KbSE/WS18KbSE_Teil5.pdf · Prof. Dr. Stephan Kleuker 315 EJB - Konzept •Standardisierte

Prof. Dr. Stephan Kleuker

602

Fazit

• CDI ermöglicht eine sehr große Entkopplung der Klassen voneinander

• Klassen werden so flexibler einsetzbar, evtl. Programmiermodel intuitiver

• im Beispiel wird „Balkon“ an Projekt programmiert, da @Inject und @...Scope ausreichen; nicht untypisch für klassisches JEE-Projekt

• CDI macht SW zur Zeit noch langsamer

• Annotations-Warfare-Area wird drastisch vergrößert

Komponentenbasierte Software-Entwicklung