190 likes | 493 Views
Google Web Toolkit. Davis Ford Software Consultant Zeno Consulting, Inc. davisford@zenoconsulting.biz http://www.zenoconsulting.biz. What Is Google Web Toolkit?. Development toolkit created, maintained, open-sourced by Google for developing complex JavaScript front-end applications
E N D
Google Web Toolkit Davis Ford Software Consultant Zeno Consulting, Inc. davisford@zenoconsulting.biz http://www.zenoconsulting.biz
What Is Google Web Toolkit? • 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? • 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? • 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 Project • Java 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
Anatomy of a GWT Project • 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) 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); } }
WebApp Architecture (antiquated) • Presentation logic is all server-side (e.g. Struts/JSP) • Life Above The Service Tier: Ganesh Prasad & Vikrant Todankar
WebApp Architecture (updated) • 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 Practices • Based 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 on • Get security right – avoid Cross-Site Request Forgery (XSRF)
MVP Pattern • Many 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
MVP Contrived Example public class Presenter { public interface Display { User getUser(); HasClickHandlersloginClick(); } 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 TextBoxnameBox; private TextBoxpassBox; private Button loginButton; public User getUser() { return new User(nameBox.getText(), passBox.getText()); } public HasClickHandlersloginClick() { return loginButton; } }
Why MVP? • Decoupling is nice • Testing matters • MVP makes it easy to test with pure JUnit + mock framework like EasyMock • Can 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
Strategies for View • Option 1: Programmatically lay it all out == BAD • Maintainability nightmare • Some things you are forced to do in CSS anyway (lack API) VerticalPanelvPanel = 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 View • Option 2: Structure in code, style in CSS == BETTER VerticalPanelvPanel = 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 View • UiBinder: New feature in GWT 2.0 allows declarative UI with XML == BETTER STILL • Structure and Style in XML Binds to simple Java view class • Easier transition for designers more comfortable with HTML/CSS • Compile time checks of UI declaration vs. bound Java class • Reduces boilerplate layout code; caveat: learn CSS very well public class View { private static ViewUiBinderuiBinder = GWT.create(ViewUiBinder.class); interface ViewUIBinder extends UiBinder<Widget, View> {} @UiFieldHorizontalPanelhPanel; @UiField Label label1; @UiField Label label2; } <ui:UiBinderxmlns: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>
Security Concerns • XSRF: 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.
Demo Application • On GitHub: http://github.com/davisford/gwt-demo • No license • Demonstrates: • MVP • UiBinder • Navigation • History • Security • GWT-RPC • CRUD with persistence layer (fake – no DB) • Spring WebMVC and Dependency Injection on Server Side