Upload
lindsey-owen
View
212
Download
0
Embed Size (px)
Citation preview
Google Web Toolkit
2/15/10
Davis Ford
Software Consultant
Zeno Consulting, Inc.
http://www.zenoconsulting.biz
What Is Google Web Toolkit?
2/15/10
Development toolkit created, maintained, open-sourced by Google for developing complex JavaScript front-end applications
Develop application in Java using your tool of choice
Java-to-JavaScript cross-compiler compiles Java code down to highly optimized and (optionally) obfuscated JavaScript + CSS and HTML
What Makes Up GWT?
2/15/10
Java → JavaScript cross-compiler
JRE emulation library: JavaScript implementations of commonly used J2SE class library (subset of: java.lang, java.util, java.io, java.sql)
UI Widget library (see GWT Showcase)
Development Server (Jetty)
Web browser GWT plugin → translates bytecode on-the-fly into DOM updates
Why?
2/15/10
Cross-browser compatibility issues
Stick to web standards (no client side runtime required)
History management & i18n support
Re-useable UI components
Support for client/server debugging
Compile-time checks with Java + better code organization / re-use / maintainability
Rapid development cycle (edit → refresh → view)
Easy to test (if designed right)
Anatomy of a GWT ProjectJava JavaScript must be
under com.domain.client.*Server code goes
anywhere not under com.domain.client.*
war/WEB-INF Standard J2EE stuff here
Server code optional – does not have to be Java, but code sharing is nice
2/15/10
Anatomy of a GWT Project
2/15/10
public class Hello implements EntryPoint {
public void onModuleLoad() {
Button b = new Button("Click me", new ClickHandler() {
public void onClick(ClickEvent event) {
Window.alert("Hello, AJAX");
}
});
RootPanel.get().add(b);
}
}
GWT Module XML (e.g. Application.gwt.xml) defines the application entry point and resource (e.g. CSS, 3rd party widgets) needed by the application
GWT EntryPoint similar to Java static void main(String[] args)
WebApp Architecture (antiquated)
2/15/10
Presentation logic is all server-side (e.g. Struts/JSP)
Life Above The Service Tier: Ganesh Prasad & Vikrant Todankar
WebApp Architecture (updated)
2/15/10
Service Oriented Front-End Architecture (SOFEA) or Service Oriented UI (SOUI)
Presentation Logic moved into Rich Client
Rich Client talks with service interface primarily for CRUD operations
Better performance on client and server side better scalability
Simpler to develop, maintain and test
GWT Best PracticesBased on
Google I/O Talk (Ray Ryan, May 2009)Based on personal experience building real
GWT apps.De-couple your design
Application Event Bus (pub/sub pattern)Model-View-Presenter pattern
Get history right early onGet security right – avoid Cross-Site Request
Forgery (XSRF)
2/15/10
MVP PatternMany different variants – most
popular in GWT is Passive View (MartinFowler.com)
Presenter handles responses to UI events; also responsible for updating the View
View is very, very thin – dumb logic, if any at all – contains layout and styles, etc.
Presenter & View communicate through well-defined interface
View has no knowledge of Presenter
2/15/10
class Passiv e View
«interface»Display
+ getUser() : User+ loginClick() : HasClickHandlers
User
+ getName() : String+ getPassword() : String
View
+ getUser() : User+ loginClick() : HasClickHandlers
Presenter
- display: Display
Model
+display
High-Level Design
2/15/10
class Class Model
AppController
Presenter
- display: Display- eventBus: EventBus- service: AsyncService
AsyncServ ice
View
«interface»Display
Ev entBus
Model
History ManagementView TransitionComponent Construction
Dispatch Events to Event HandlersRegisters Event Handlers
Data Transfer Object Communicates with Server
UI ComponentsLayoutStyle
+display
+eventBus
+service
MVP Contrived Example
2/15/10
public class Presenter {
public interface Display {
User getUser();
HasClickHandlers loginClick();
}
public Presenter(Display display, EventBus bus, AsyncService service) {
display.loginClick().addClickHandler(new ClickHandler() {
User user = display.getUser();
service.login(user);
});
}
}
public class View extends Composite implements Presenter.Display {
private TextBox nameBox;
private TextBox passBox;
private Button loginButton;
public User getUser() { return new User(nameBox.getText(), passBox.getText()); }
public HasClickHandlers loginClick() { return loginButton; }
}
Why MVP?Decoupling is niceTesting mattersMVP makes it easy to test with pure JUnit + mock
framework like EasyMockCan test almost all UI code with unit tests Some GWT classes cannot be instantiated without
JavaScript cross-compiler (e.g. GWT.* Cookies.*, Widget, etc.) – push these dependencies under interfaces or leave them encapsulated in the View where you don’t care
GwtTestCase: bootstrap takes ~20 seconds = yuck
2/15/10
Strategies for View Option 1: Programmatically lay it all out == BADMaintainability nightmareSome things you are forced to do in CSS anyway (lack API)
2/15/10
VerticalPanel vPanel = new VerticalPanel();vPanel.setHeight(200px);vPanel.setWidth(300px);vPanel.setCellSpacing(4);Button button = new Button(“Click Me”);button.setSize(“25px”, “10px”);vPanel.add(button);
Strategies for ViewOption 2: Structure in code, style in CSS ==
BETTER
2/15/10
VerticalPanel vPanel = new VerticalPanel();vPanel.setStyleName(“vPanelStyle”);Button b = new Button(“Click Me”);b.setStyleName(“myButton”);vPanel.add(b);
.vPanel { height: 200px; width: 3000px; etc…}
Strategies for ViewUiBinder: New feature in GWT 2.0 allows declarative UI with
XML == BETTER STILLStructure and Style in XML Binds to simple Java view classEasier transition for designers more comfortable with
HTML/CSSCompile time checks of UI declaration vs. bound Java classReduces boilerplate layout code; caveat: learn CSS very well
2/15/10
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'> <g:HorizontalPanel ui:field=“hPanel”> <g:Label ui:field=“label1”>Keep your ducks</g:Label> <g:Label ui:field=“label2”>in a row</g:Label> </g:HorizontalPanel></ui:UiBinder>
public class View { private static ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class);
interface ViewUIBinder extends UiBinder<Widget, View> {}
@UiField HorizontalPanel hPanel;@UiField Label label1;@UiField Label label2;}
Security ConcernsXSRF: Attacker lures you to a page on their
site with a link back to your site that calls a remote service – rides in on the Cookie, b/c you’ve already authenticated.Fix: Dupe cookie value and submit it as form
data along with all remote service requests.Server compares copy of cookie in form with
actual cookie in session. If they don’t match, you know XSRF occurred.
Same origin-policy ensures that third-party site cannot access the cookie in your site.
2/15/10
Demo ApplicationOn GitHub: http://github.com/davisford/gwt-demoNo licenseDemonstrates:
MVPUiBinderNavigationHistorySecurityGWT-RPCCRUD with persistence layer (fake – no DB)Spring WebMVC and Dependency Injection on Server
Side2/15/10