gwt integration with vaadin - javacro · between gwt client and server 2. vaadin connectors use...

80
GWT integration with Vaadin Peter Lehto @peter_lehto expert & trainer

Upload: others

Post on 21-May-2020

20 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

GWT integration with Vaadin

Peter Lehto @peter_lehto

expert & trainer

Page 2: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Vaadin &

GWT

GWT Transport

mechanisms

Page 3: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

QA

Vaadin

Connectors

Web components

with Polymer

Page 4: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Vaadin &

GWT

Page 5: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC
Page 6: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Server driven UI framework with GWT

based thin client

Page 7: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

UI

Browser

Page 8: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

UI

Browser

Widgets

Page 9: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Them

e UI

Browser

Widgets

Page 10: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Them

e UI

Browser

Backend

Server

Widgets

Page 11: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Them

e UI

Browser

Backend

Server

Widgets

Service (GWT-RPC)

Page 12: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Backend

Server

Page 13: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

UI Backend

Server

Page 14: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

UI Backend

Server

Widgets Components

Page 15: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Them

e

Browser

UI Backend

Server

Widgets Components

Page 16: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Them

e

Browser

UI Backend

Server

Widgets Components

Page 17: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

User Interface Components

Page 18: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Developer

Productivity

Rich

UX

Page 19: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Vaadin += GWT

Page 20: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC
Page 21: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC
Page 22: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

GWT Transport

mechanisms

Page 23: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

RequestBuilder RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);try { builder.sendRequest(requestDataString, new RequestCallback() { @Override

public void onResponseReceived(Request request, Response response) { int statusCode = response.getStatusCode(); String text = response.getText();

} @Override

public void onError(Request request, Throwable exception) { // TODO Handle asynchronous problems

} }); } catch (RequestException e) { // TODO Handle synchronous problems}

Page 24: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

RequestBuilder

Good

• It just works

Page 25: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

RequestBuilder

Good

• It just works

Bad

• Very low level

Page 26: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

What to send?

Page 27: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Contact public class Contact { private String name; private int yearOfBirth;

private List<String> emailAddresses; private Address address;

public static class Address { private String street; private String city; } // + Getters and setters}

Page 28: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

String conversion

String data = contact.getName();data += "," + contact.getYearOfBirth();String[] parts = data.split(",");contact.setName(parts[0]);contact.setYearOfBirth(Integer.parseInt(parts[1]));

Page 29: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

String conversion

String data = contact.getName();data += "," + contact.getYearOfBirth();String[] parts = data.split(",");contact.setName(parts[0]);contact.setYearOfBirth(Integer.parseInt(parts[1]));

Page 30: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

JSON { name: "John Doe", yearOfBirth: 1900, address: { street: "Happy Street 1", city: "Turku" }, emailAddresses: ["[email protected]", "[email protected]"]}

Page 31: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

JSONValue parsing JSONObject json = JSONParser.parseStrict(string).isObject();contact.setName(json.get("name").isString().stringValue());contact.setYearOfBirth( (int) json.get("yearOfBirth").isNumber().doubleValue());contact.setAddress( parseAddress(json.get("address").isObject()));

JSONArray emailAddresses = json.get("emailAddresses").isArray(); for (int i = 0; i < emailAddresses.size(); i++) { contact.getEmailAddresses().add(

} }

Page 32: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

JSONValue

Good

• It’s standard • Human readable • Compact format

Page 33: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

JSONValue

Good

• It’s standard • Human readable • Compact format

Bad

• Not completely typesafe

• Boilerplate • Client only

Page 34: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

What about the server?

Page 35: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Jackson on the server ObjectMapper mapper = new ObjectMapper();try { Contact contact = mapper.readValue(string, Contact.class);} catch (VariousExceptions e) { // Do something sensible}

Page 36: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Jackson and GWT? - gwt-jackson

Page 37: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

gwt-jackson public static interface ContactMapper extends ObjectMapper<Contact> {}

public Contact parseContact(String jsonString) { ContactMapper mapper = GWT.create(ContactMapper.class); Contact contact = mapper.read(jsonString); return contact;}

Page 38: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Jackson

Good

• Minimal boiler plate

• Can share codebetween serverand client

Bad

• Only creatingand readingStrings

Page 39: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Where to send?

Page 40: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Remote procedure call public interface ContactService extends RemoteService { public void saveContact(Contact contact); public List<Contact> getContacts();}

public interface ContactServiceAsync { public void saveContact(Contact contact, AsyncCallback<Void> callback); public void getContacts(AsyncCallback<List<Contact>>

}

Page 41: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

GWT-RCP

Good

• Simple butpowerful concept

• Default solution • Optimized

Bad

• Sending largeobject graph

• Polymorphismproblems

Page 42: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Prefer JSON + REST?- me too :)

Page 43: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

REST GET /contacts

DELETE /contacts/5

PUT /contacts { name: “John Doe”, ... }

Page 44: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

JAX-RS @Path("/contacts")public interface ContactsService { @GET public List<Contact> listContacts();

@Path("/{id}") @DELETE public void deleteContact(@PathParam("id") int id);

@PUT public void createContact(Contact contact);}

Page 45: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Vaadin Connectors

Page 46: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

So how about Vaadin?- Put server in charge!

Page 47: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC
Page 48: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

State synchronization public class ContactState extends SharedState { public String name; @DelegateToWidget public int yearOfBirth;}

@OnStateChange("name")private void updateName() { doSomethingWithTheName(getState().name);}

Page 49: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

RPC public interface ContactRpc extends ServerRpc { public void deleteContact(int id);} // Register RPC handler on the serverregisterRpc(new ContactRpc() { @Override public void deleteContact(int id) { ContactDAO.deleteById(id);} }); // Send RPC from the clientpublic void sendDelete(int contactId) { getRpcProxy(ContactRpc.class).deleteContact(contactId);}

Page 50: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Server

Button

Page 51: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

VButton

Button

Page 52: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

VButton

ButtonConnector

Button

Page 53: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

VButton

ButtonConnector

SharedState

Button

SharedState

Page 54: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

SharedState

SharedState

Button

VButton

ButtonConnector

Page 55: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

SharedState

SharedState

RPC

RPC

Button

VButton

ButtonConnector

Page 56: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

SharedState

SharedState

RPC

RPC

Button

VButton

ButtonConnector

Page 57: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

SharedState

SharedState

RPC

RPC

Button

VButton

ButtonConnector

Page 58: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Browser

Server

Button

VButton

ButtonConnector

SharedState

SharedState

RPC

RPC

Page 59: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

server

client

Component

Widget

Connector

RPC

State

Page 60: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

ButtonConnector @Connect(Button.class)public class ButtonConnector extends AbstractComponentConnector implements ClickHandler, FocusHandler {

public void init() { getWidget().addClickHandler(this); }

@OnStateChange({ "caption", "captionAsHtml" }) void setCaption() { getWidget().setCaptionText(getState()); }

Page 61: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

public void onClick(ClickEvent event) { getRpcProxy(ButtonServerRpc.class). click(buildDetails(event)); } }

Page 62: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

ButtonState public class ButtonState extends AbstractComponentState { …

public String caption;public boolean disableOnClick;public int tabIndex;…

}

Page 63: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

ButtonServerRPC public interface ButtonServerRpc extends ServerRpc {

public void click(MouseEventDetails mouseEventDetails);

}

Page 64: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Server RPC implementation public class Button extends AbstractComponent { … private ButtonServerRpc rpc = new ButtonServerRpc() { public void click(MouseEventDetails details) { fireClick(details); } … }

Page 65: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Vaadin Connectors

Good

• Stateful server • Websocket

support • Integrated

JSON

Bad

• Stateful server • Tied to

framework

Page 66: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Web components

with Polymer

Page 67: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Reuseable HTML components!

Page 68: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Problem: Unique DOM tree

Page 69: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Solution: Shadow DOM

Page 70: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Encapsulation

Page 71: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

What shadow DOM looks like?

Page 72: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

How? With Polymer

polymer-project.org/

Page 73: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

<v-grid>

Page 74: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Vaadin Grid Client Widget

Expose JavaScript API via

JsInterop from GWT 2.8

Use Shadow DOM and HTML

imports from Polymer

Page 75: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

@JsNamespace(JS.VAADIN_JS_NAMESPACE) @JsExport @JsType public class GridComponent… … private final Grid grid; // Grid widget

public JSColumn addColumn(JSColumn jsColumn, Object beforeColumnId) { grid.addColumn } …

Page 76: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

@JsType public interface JSColumn {

@JsProperty String getName();

@JsProperty void setName(String s);

Page 77: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

<link rel='import' href='vaadin-grid-import.html'> <link rel='import' href='../bower_components/polymer/polymer.html'> <link rel="stylesheet" href="vaadin-grid.css" shim-shadowdom>

<dom-module id="v-grid"> <template> </template> </dom-module>

<script> var prototype = { is: “v-grid", properties: { … }, created: function() {

this._grid = new vaadin.GridComponent(); }, attached: function() {

this._grid.attached(this, Polymer.dom(this).querySelector(“table”), Polymer.dom(this.root));

},

… } </script>

Page 78: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

GridWidget (js)

GridComponent (js)

polymer.html

webcomponents.jsdemo.html vaadin-grid.html

Page 79: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Lessons learned today

1. There are several ways of communicating between GWT client and server

2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

3. gwt-jackson with REST is very interesting option

4. Polymer allows browsers to support features needed forfor web components

Page 80: GWT integration with Vaadin - JavaCRO · between GWT client and server 2. Vaadin Connectors use custom hybrid of JSON and RequestBuilder wrapped to higher level SharedState and RPC

Thank you!Peter Lehto @peter_lehto

expert & trainer