Year one ein-jahr_mit_jsf_2-2

Preview:

DESCRIPTION

Der erste Geburtstag von JEE 7 bietet eine gute Möglichkeit, auf das letzte Jahr zurückzuschauen und die Praxistauglichkeit der neuen JSF-Features zu bewerten. War HTML Friendly Markup ein Schritt nach vorn? Ist der Einsatz von Resource Library Contracts ein Vorteil? Wie fühlt sich Faces Flow in der Praxis an? Können Protected Views einfach eingesetzt werden? Der Vortrag stellt die Ergebnisse aus den ersten JEE-7-Projekten vor und zeigt anhand von praktischen Beispielen, wie die neuen Features am besten genutzt werden können.

Citation preview

Stephan Müller| open knowledge GmbH

Year One – Ein Jahr mit JSF 2.2

Ein Jahr mit JSF 2.2

... und Geschenkegibt’s auch

Unsere allseits beliebte OK-

Tasse

JSF 2.2

JSR-344- Mojarra (RI) v2.2.6- Apache MyFaces v.2.2.4

Features- Big Ticket (4x)- Medium Size- Small Size (u.a. Bugfixes)

ergänzende JSRs- EL 3.0 (JSR-341)

Implemen-tierungen

Laufzeit-umgebungen

Utility-Bibliotheken

Komponenten-bibliotheken

JSF 2.2 Ökosystem

Year One ...

Mojarra 2.2.012. Juni 2013 JSR-344 RI

MyFaces 2.2.0:14. Januar 2014

Q2 2013 Q3 2013 Q4 2013 Q1 2014 Q2 2014

Primefaces 4.021. Oktober 2013

IceFaces 4.0 Beta24. März 2014

“Glassfish“ News04. November 2013

WildFly 8.0.0 Final11. Februar 2014 JEE7 certified

Richfaces 4.5/5.0Demnächst ...

Glassfish 4.0Mai 2013 JEE7 certified

JSF 2.2 Projekt

Technologie- Java EE7- JBoss WildFly- MySQL- viel JavaScript & AJAX

Team- 4 JSF-Neulinge- 2 Coaches

UI-Requirements- Dashboard mit

Widgets- Overlay-Formulare- File-Upload für

mehrere Dateien- Diagramme zur

Datenvisualisierung

JSF 2.2 Lessons learned

1) HTML Friendly Markup

2) Resource Library Contracts

3) Faces Flow4) ViewScope5) ViewActions6) FileUpload

7) CDI Injection in JSF artifacts

8) CSRF Protection9) Ajax resetValues10)Configurable

resource directory11)Multiple Forms *

HTML Friendly Markup

IdeeStandardisierter HTML5 Support

in JSF

Konzepte- Pass-through

Attributes- Pass-through

Elements

Pass-through Attributes

KonzeptUnterstützung für HTML5 und data-* Attribute

Lessons learnedGut geeignet für bestehende Anwendungen & composite-components

Verwendung- Name-Spaced Attribute

(e.g. “p:placeholder“)- <f:passThroughAttribute/

>- <f:passThroughAttributes

/>

Pass-through Attributes

<!DOCTYPE html><html xmlns="http://ww.w3.org/1999/xhtml" ...>

<h:head><title>...</title></h:head><h:body> <h:form> <h:outputLabel for="email" value=“E-Mail"/> <h:inputText id="email“ value="#{...}"> <f:passThroughAttribute name="type" value="email"/> <f:passThroughAttribute name="placeholder" value=“E-mail“/> </h:inputText> ... </h:form> </h:body></html>

Pass-through Attributes

<!DOCTYPE html><html xmlns="http://ww.w3.org/1999/xhtml" ... xmlns:p="http://xmlns.jcp.org/jsf/passthrough"><h:head><title>...</title></h:head><h:body> <h:form> <h:outputLabel for="email" value="E-Mail"/> <h:inputText id="email" value="#{...}"> p:type="email" p:placeholder="E-Mail"/>

...

</h:form> </h:body></html>

Pass-through Elements

Konzept- Volle Kontrolle

über HTML- Trennung von

Design & UI-Logik- HTML mit JSF

anreichern

Lessons learned- hohe Einstiegshürde- IDE Validierung wertlos- Schlechte Lesbarkeit

durch Namespaced Attribute

Problem- Unübersichtlicher

Code(starker Mix aus HTML und JSF-Tags)

Pass-through Elements

<!DOCTYPE html><html xmlns=“http://www.w3.org/1999/xhtml”>

<head><title>...</title></head><body> <form> <label>Vorname</label> <input type="text“ id=“FirstName”/>

... </form> </body></html>

Pass-through Elements

<!DOCTYPE html><html xmlns=“http://www.w3.org/1999/xhtml” xmlns:jsf=“http://xmlns.jcp.org/jsf" ...><head jsf:id=“head“><title>...</title></head><body jsf:id=“body“> <form jsf:id=“form“> <label>Vorname</label> <input type="text“ jsf:id="firstName“ jsf:value="#{...}“/> <h:message for="firstName"/> ... </form> </body></html>

Pass-through Elements

<h:inputText id="firstName" value="#{...}" readonly="#{...}" disabled="#{...}" rendered="#{...}" maxlength="30" title="Vorname" styleClass="…"/>

<input type=“text” jsf:id="firstName" jsf:value="#{...}" jsf:readonly="#{...}" jsf:disabled="#{...}" jsf:rendered="#{...}" length="30" title="Vorname” class="…"/>

Resource Library Contracts

Konzept- Theming- mandanten-

spezifisches Look & Feel

Contract- Facelet-

Template- CSS- Bilder- JavaScript

Lessons learned- Erhöhte Komplexität für

Resourcen-Verteilung durch weiteres Verzeichnis

- Schlechte IDE-Unterstützung

Resource Library Contracts

demo.war |- contracts Contracts | - default Theme “default“ |- template.xhtml |- ... |- resources Resourcen | - ... |- WEB-INF | - classes Java Klassen und Ressourcen | - lib Java Libraries | - faces-config.xml Konfigurationsdatei (optional) | - web.xml Deployment Deskriptor (optional)

Resource Library Contracts

<!DOCTYPE html><html xmlns=“http://ww.w3.org/1999/xhtml” ...>

<head jsf:id=“head“><title>...</title></head><body jsf:id=“body“> <f:view contracts=“#{currentTheme}“> <form jsf:id=“form“> ... </form> <f:view></body></html>

Resource Library Contracts

<?xml version="1.0" encoding="UTF-8"?><faces-config ...> <application> ... <!– theme configuration --> <resource-library-contract> <contract-mapping> <description>Default theme</description> <url-pattern>*</url-pattern> <contracts>default</contracts> </contract-mapping> </resource-library-contract> </application></faces-config>

Faces Flow

Knotentypen- View Node- Return Node- Flow Call Node- Switch Node- Method Call Node

Lessons learned- Schlecht dokumentiert- Wenig komplexe

Beispiele- Fehler in faces-

config.xsd

Konzept- UI Prozesse realisieren- Definierte

Start-/Endpunkte- Navigation auf Flow

beschränken

Faces Flow

<?xml version="1.0"?><faces-config version="2.2" ...> <flow-definition id="flow"> <start-node>first</start-node> <view id="first"> <vdl-document>/flow/page1.xhtml</vdl-document> </view> ... <flow-return id="flow-return"> <from-outcome>/index.xhtml</from-outcome> </flow-return>

<initializer>#{...}</initializer> <finalizer>#{...}</finalizer> </flow-definition></faces-config>

Faces Flow

@Named@javax.faces.flow.ViewScoped("flow")public class FlowBean implements Serializable {

@PostConstruct void init() { ... }

public void initializeFlow() { ... }

public void finalizeFlow() { ... }

...}

ViewScope

KonzeptBean existiert über mehrere Requests bis die View verlassen wird

LösungenViewAccessScope verwenden(Apache Deltaspike)

ProblemGET-Request (F5) erzeugt ViewScoped Bean neu

ViewScope

@Named@javax.faces.view.ViewScopedpublic class UserDetailBean implements Serializable {

private User user;

@PostConstruct void init() { ... }

public void load() { ... }

}

ViewScope

@Named@org.apache.deltaspike.core.api.scope.ViewAccessScopedpublic class UserDetailBean implements Serializable {

private User user;

@PostConstruct void init() { ... }

public void load() { ... }

}

ViewAction

Konzept- Ausführung von

Logik vor dem Rendern der Seite

- Unterstützung für GET-Requests mit view-Parametern

Vorteile- Aufruf “nur“ beim

initialen Request- Standardnavigation

(e.g. redirect) möglich

Lessons learned TOP FEATURE !!!(auch für FacesFlow)

ViewAction

<!DOCTYPE html><html xmlns=“http://ww.w3.org/1999/xhtml” ...>

<head jsf:id=“head“><title>...</title></head><f:metadata> <f:viewParam name="id" value="#{userDetailBean.id}“ /> <f:viewAction action="#{userDetailBean.load}“ /></f:metadata><body jsf:id=“body“> <form jsf:id=“form“>

...

</form> </body></html>

ViewAction

@Named@ViewScopedpublic class UserDetailBean implements Serializable {

private User user;

@PostConstruct void init() { ... }

public void load() { ... }

}

FileUpload

KonzeptStandardisierter FileUpload

Lessons learned- kein Support für fancy UI

(e.g. Fortschrittsbalken)- keine parallelen Uploads

möglich

ProblemAjax Requests mehrerer h:inputFile Komponenten werden nicht gequeued

FileUpload

<!DOCTYPE html><html xmlns=“http://ww.w3.org/1999/xhtml” ...>

<head jsf:id=“head“><title>...</title></head><body jsf:id=“body“> <form jsf:id=“form“ jsf:enctype="multipart/form-data“> <label>Bild</label> <f:inputFile id=“picture“ value=“#{...}“> <f:validatorId=“pictureValidator“> <f:ajax> </f:inputFile> <h:message for=“picture“ />

</form> </body></html>

JSF 2.2 Lessons learned

1) HTML Friendly Markup ✓

2) Resource Library Contracts ✓

3) Faces Flow ✓4) ViewScope ✓5) ViewActions ✓6) FileUpload ✓

7) CDI Injection in JSF artifacts

8) CSRF Protection9) Ajax resetValues10)Configurable

resource directory11)Multiple Forms *

CDI Injection in JSF artifacts

KonzeptCDI Injection in allen JSF Artefakten

Lösungen- OmniFaces- Converter/Validator als

RequestScoped CDI Bean realisieren

ProblemKeine CDI Injection für Converter / Validatoren

CDI Injection in JSF artifacts

@FacesValidatorpublic class UniqueUserValidator implements Validator {

@Inject private UserRepository repository;

@Override public void validate(...) {

...

}}

CDI Injection in JSF artifacts

@Named@RequestScoped@FacesValidatorpublic class UniqueUserValidator implements Validator {

@Inject private UserRepository repository;

@Override public void validate(...) {

...

}}

CDI Injection in JSF artifacts

<!DOCTYPE html><html xmlns=“http://www.w3.org/1999/xhtml” ...><head jsf:id=“head“><title>...</title></head><body jsf:id=“body“> <form jsf:id=“form“> <label>Vorname</label> <input type=“text“ jsf:value=“#{...}”> <f:validator binding=“#{uniqueUserValidator}”/> </input> ... </form> </body></html>

CSRF Protection

IdeeSchutz gegen CSRF Angriffe

Lessons learnedJede View muss einzeln definiert werden

Konzept- GET-Request wird

verhindert(ProtectedViewException)

- Zugriff nur mit Token & POST-Navigation

CSRF Protection

<?xml version="1.0" encoding="UTF-8"?><faces-config ...> ... <!– protected views configuration --> <protected-views> <url-pattern>/secure/index.xhtml</url-pattern> <url-pattern>/secure/edit.xhtml</url-pattern> <url-pattern>...</url-pattern> </protected-views>

...</faces-config>

Configurable Resource Folder

Lessons learned- in der Praxis leider mit

Seiteneffekten

IdeeBrowser-Zugriff auf /resource verhindern

Problem- EL-Expressions in CSS

notwendig(für Bilder)- IDE kann

Verzeichnisse nicht mehr auflösen

KonzeptPfad von /resource konfigurierbar

Configurable Resource Folder

<web-app version="3.0" ...> <context-param> <param-name> javax.faces.WEBAPP_RESOURCES_DIRECTORY </param-name> <param-value>/WEB-INF/resources</param-value> </context-param> <context-param> <param-name> javax.faces.WEBAPP_CONTRACTS_DIRECTORY </param-name> <param-value>/WEB-INF/contracts</param-value> </context-param></web-app>

Ajax resetValues

IdeeBeim Schließen eines Overlay sollen die UIInput Komponenten “resettet“ werden

Erfahrungen- @form funktioniert

nicht- clientId aller

betroffenen Komponenten muss explizit angegeben werden

Ajax resetValues

<b:overlay> <h:form id="form“> <h:outputLabel for="userName" value="UserName"/> <h:inputText id="userName" value="#{...}"/> <h:message for="userName" />

<h:outputLabel for="email" value="E-Mail"/> <h:inputText id="email" value="#{...}"/> <h:message for="email"/>

<h:commandButton value="Schließen"/> <f:ajax render="userName email“ resetValues="true“ listener="#{...}" /> </h:commandButton> </h:form></b:overlay>

Multiple Forms *

Lessons learned- * bekannter Fehler

(PUBLIC-790)- Lösung von BalusC

(Communication in JSF 2.0)

Anforderung- mehrere

Formulare (h:form) auf einer Seite

- AJAX

ProblemHiddenInput Element javax.faces.ViewState wird nicht zu 2./3./... Formular hinzugefügt

JSF 2.2 Lessons learned

1) HTML Friendly Markup ✓

2) Resource Library Contracts ✓

3) Faces Flow ✓4) ViewScope ✓5) ViewActions ✓6) FileUpload ✓

7) CDI Injection in JSF artifacts ✓

8) CSRF Protection ✓9) Configurable

resource directory ✓

10)Ajax resetValues ✓11)Multiple Forms ✓

Exkurs:Expression Language 3.0

Expression Language 3.0

- Neue Operatoren

- Collection construction

- Lambda expressions

- Static field & method references

x = bean.value; 'Wert ' += x

['a', 'b', 'c'] // List{'a':1, 'b':2, 'c':3} // Map

(x -> x + 1)(10) // 11

Integer.MAX_VALUEInteger.toHexString(16)

Expression Language 3.0

<!-- Example: Map Construction --><h:inputText id=“email“ value=“#{...}“> <f:passThroughAttributes value="#{{'placeholder':'test', 'type':'email'}}"/></h:inputText>

<!-- Example: List Construction --><ui:repeat var="item" value="#{['a', 'b', 'c']}"> ...</ui:repeat>

<!-- Static Field / :( not working (EL_SPEC-16) --><h:outputText value="#{Integer.MAX_VALUE}"/>

Fazit

- War HTML Markup Friendly ein Schritt nach vorn?

- Wie fühlt sich FacesFlow in der Praxis an?

- Können Protected Views einfach eingesetzt werden?

Q&A

Gibt es noch Fragen?

Dann los ...

Weitere Infos zu JSF 2.2

Java EE 7 Tutorialhttp://docs.oracle.com/javaee/7/tutorial/doc/home.htm

JSF 2.2 (JSR-344) http://javaserverfaces.java.net EL 3.0 (JSR-341) https://java.net/projects/el-spec

BalusC Weblog http://balusc.blogspot.de Michael Kurz‘s JSF Weblog http://jsflive.wordpress.com

Über open knowledge und den Speaker

> unabhängiges, inhabergeführtes Softwareentwicklungs- und Beratungsunternehmen aus Oldenburg

> Kernkompetenzen im Enterprise- und Mobile-Computing

> Stephan Müller

> Enterprise Architect

facebook.com/openknowledge

twitter.com/_openknowledge

twitter.com/muellerst

Recommended