JSF vs. GWT? JSF und GWT!

Preview:

DESCRIPTION

Slides of the JAX 2014 talk

Citation preview

Christian Kaltepoth | ingenit GmbH & Co. KG

JSF vs. GWT? JSF und GWT!

JavaServer Faces

• „Bodenständige Technologie“• Formularbasierte Anwendungen• Data Lifecycle

– z.B. Konvertierung + Validierung

• Mächtige Komponenten• Support für AJAX, HTML5, etc.

Aber...

• Server als zentrale Instanz– Rendering, Validierung, etc.– Viel Kommunikation mit dem Server

• PPR reicht oft nicht aus• State, State, State, ...

– Muss synchron gehalten werden– Ohne langlebige Scopes geht nichts

Ein Blick über den Tellerrand...

GWT[ i t]ɡʉˑ ˑ

GWT

• „Development toolkit for building [...] complex browser-based applications“

• Veröffentlicht 2006• Geleitet von:

– 2006-2012: Google– Seit 2012: Steering Committee

GWT Compiler

Was ist GWT?

Warum GWT statt JavaScript?

• Java als etablierte Sprache• Gewohntes Tooling

– IDE, Build Tools, Testing, ....

• Starke Typisierung– Compiler Checks, Static Code Analysis, ...

• GWT kümmert sich um:– DOM Garbage Collection– Inkompatibilitäten zwischen Browsern

Server Client

Shared Code!

GWT

• GWT Compiler• Client Bundles• Deferred Binding• RequestBuilder• I18N• Logging• UI Components

• RequestFactory• Testing• GWT-RPC• UI Binder• Editors• JSNI• Code Splitting

GWT

• GWT Compiler• Client Bundles• Deferred Binding• RequestBuilder• I18N• Logging• UI Components

• RequestFactory• Testing• GWT-RPC• UI Binder• Editors• JSNI• Code Splitting

Ist GWT überhaupt noch„State of the Art“?

Google Sheets

Google Shopping Express

Evernote

„Hello World!“ mit GWT

DEMO

Kann man JSF und GWT kombinieren?

Ja, das geht! ☺

JSF & GWT

• Das Ziel:– Clientseitige Funktionalität– Mehr Interaktivität– User Experience

• Die Herausforderung:– Interaktion mit JSF Komponenten– JSF Lifecycle nicht beeinflussen

JSF + GWT

Eine Beispielanwendung

Was ist das BMS?

• Bäckerei Verwaltungssoftware• JEE7 Anwendung mit JSF 2.2• Artikelmanagement

– Stammdaten, Kosten, Preise, ...

• Rezeptverwaltung• Berechnung der Produktionskosten

Sprint 23: Einkaufspreise

Featurewunsch

„Graphische Aufbereitung der Auswirkungen

von Einkaufspreisveränderung auf die Herstellungskosten

der betroffenen Artikel.“

Probleme

• Kostenberechnung im Backend!• JavaScript Komponente sinnvoll!

– Interaktivität (Tooltips, etc.)

• Berechnung auf dem Server?– RTT problematisch!

• Neuimplementierung der Berechnungslogik in JavaScript?

Lösungsansatz

• Implementierung mittels GWT– Eingaben aus JSF Komponenten auf dem

Client auslesen– Berechnungslogik als Shared Code– Nutzung von JavaScript Chart Library für

die Grafik (d3.js)

BMS DEMO

Was brauchen wir?

• Interaktion mit JSF Komponenten➡ GWT Components

• Integration der JavaScript Library➡ JSNI

• Kommunikation mit Server➡ Remoting

GWT Components

GWT Components

• Realisiert als „einfache“ Klassen• Unterklassen von Widget• Tiefe Vererbungshierarchie• Verschiedene Typen:

– Widgets / Panels / Composites

• Component > DOM Element + Kinder

Klassenhierarchie

Quelle: Book of Vaadin - https://vaadin.com/book/

Beispiel: PasswordTextBox

GWT Components

• Basic: – Button– RadioButton– Checkbox– Textbox– Textarea– Listbox– ...

• Advanced:– DatePicker– MenuBar– Tree– SuggestBox– CellTable– Dialog– ...

Komponentenbaum

Label label = new Label("Name:");

TextBox textbox = new TextBox();textbox.setText("Christian");

FlowPanel panel = new FlowPanel();panel.add(label);panel.add(textbox);

RootPanel.get().add(panel);

Eigene Komponenten

<input type="input" placeholder="Enter email" />

Eigene Komponenten

public class Html5TextBox extends TextBox {

public void setPlaceholder(String value) { getElement().setPropertyString("placeholder", value); }

public String getPlaceholder() { return getElement().getPropertyString("placeholder"); }

}

Für uns interessant...<input id="foobar" type="text" />

Element element = Document.get().getElementById("foobar");

TextBox textBox = TextBox.wrap(element);

textBox.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { // ... }});

Was heißt das?

• Zugriff auf DOM Element der JSF Komponenten ist einfach möglich

• Erlaubt uns...– ... aktuelle Werte zu lesen– ... den Zustand zu verändern– ... Listener zu registrieren

JSNI(JavaScript Native Interface)

„We think of JSNI as the web equivalent of inline

assembly code.“

Quelle: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html

JSNI Beispiel public void someMethod() {

sayHello(); }

private native void sayHello() /*-{

alert('Hello World!');

}-*/;

Beispiel: jQuery Integration

public void someMethod() {

fadeOut("foobar");

}

private native void fadeOut(String className) /*-{

$wnd.jQuery('.' + className).hide(800);

}-*/;

Overlay Types

public native <????????> getKonferenz() /*-{

var konferenz = { name : 'JAX', jahr : 2014 }; return konferenz;

}-*/;

Overlay Typespublic class Konferenz extends JavaScriptObject {

protected Konferenz() {}

public final native String getName() /*-{ return this.name; }-*/;

public final native int getJahr() /*-{ return this.jahr; }-*/;

}

Overlay Typespublic native Konferenz getKonferenz() /*-{

// ...

}-*/;

public void someMethod() {

Konferenz konferenz = getKonferenz();

Window.alert("Hello " + konferenz.getName());

}

Was heißt das?

• Einbindung von JavaScript Komponenten problemlos möglich

• Overlay Types erlauben:– Zugriff auf JavaScript Objekte– „Parsen“ von JSON Dokumenten

Remoting

Optionen für Remoting

• Standard GWT– GWT RPC– RequestBuilder– ...

• 3rd Party Bibliotheken– RestyGWT– ...

GWT RPC

• RPC Framework auf Basis von Servlets• Pro:

– Standard GWT– Geteilte Modellobjekte

• Contra:– Proprietäres Datenformat (kein JSON)– Relativ viele Klassen– Performance

RequestBuilder

• Für GWT optimierter HTTP Client• Pro:

– Standard GWT– Nutzung von Standard JSON APIs

• Contra:– Benötigt Overlay Types– Manuelles Erstellen der URL

JAX-RS Resource@Path("/")public class ZutatenResource {

@GET @Path("/zutat/{name}") @Produces("application/json") public Zutat getByName( @PathParam("name") String name) {

// ...

}

}

JAX-RS Resource

RestyGWT Clientpublic interface ZutatenClient extends RestService {

@GET @Path("/zutat/{name}") public void getByName( @PathParam("name") String name, MethodCallback<Zutat> callback);

}

RestyGWT ClientZutatenClient client = GWT.create(ZutatenClient.class);

client.getArtikel("Zucker", new MethodCallback<Zutat>() {

@Override public void onSuccess(Method method, Zutat response) { // ... }

@Override public void onFailure(Method method, Throwable e) { // ... }

});

Zusammenfassung

GWT RPC

RequestBuilder

RestyGWT

Standard GWT + + -

Shared Model Classes + - +

JSON via JAX-RS - + +

Was heißt das?

• Kommunikation mit dem Server auf verschiedene Arten möglich

• Wir verwenden RestyGWT:– Nutzung von JAX-RS– Modellobjekte als Shared Code

• Funktioniert auch mit JPA Entitäten!

– Stark typisierte Client API

Time for...Source Code!

Fazit

• JSF & GWT lassen sich kombinieren• Keine „Lösung für Alles“• Kann sinnvoll sein, wenn...

– geteilter Code benötigt wird– bestehende JSF Anwendungen mehr

„Interaktivität“ benötigen– Typensicherheit gewünscht wird

Vielen Dank für die Aufmerksamkeit!

https://github.com/chkal/jax14-jsf-gwt

Christian Kaltepothkaltepoth@ingenit.com @chkal

Recommended