Gwt app start to finish

Preview:

Citation preview

Google Confidential and Proprietary

Course materials

All course materials are available on USB flash drive

Copy the following from the USB drive to your computer• Eclipse 3.6.2 (if you don’t already have it)

• gpe-2.3-alpha-eclipse3.6.zip

• gwt-tutorial.zip

Install zipped update sites now to save time in Lab 1

1

Google Confidential and Proprietary 2

GWT App start to finishA hands-on tutorial building GWT using GPE

Presented by:

Rajeev DayalEric ClaybergDan Rubel

Client Logo

Google Confidential and Proprietary

Agenda

Introduction

GPE Overview

Google APIs

Lab 1

GWT Overview

GWT and GPE

Lab 2

Advanced Topics

3

GWT = Google Web Toolkit

GPE = Google Plugin for Eclipse

Google Confidential and Proprietary

Introduction

Rajeev Dayal

4

Eric Clayberg Dan Rubel

Google Confidential and Proprietary

Course materials

All course materials are available on USB flash drive

Copy the following from the USB drive to your computer• Eclipse 3.6.2 (if you don’t already have it)

• gpe-2.3-alpha-eclipse3.6.zip

• gwt-tutorial.zip

Install zipped update sites now to save time in Lab 1

5

Google Confidential and Proprietary

GPE OverviewA brief introduction to Google Plugin for Eclipse

6

Google Confidential and Proprietary

Google Plugin for Eclipse

7

GoogleAPIs

GPE

Google Confidential and Proprietary

Google Plugin for Eclipse

Wizards, Quick Fixes, Launching, Optimization, Deployment

8

Google Confidential and Proprietary

GWT Designer

Robust visual editing of GWT UI code

9

Google Confidential and Proprietary

Development Cycle

10

HitRefresh

QuickTest

WriteCode

Google Confidential and Proprietary

GPE Dev Mode

11

Google Confidential and Proprietary

Debug in GPE Dev Mode

12

Google Confidential and Proprietary

Compile for production

13

Your app running here.No plugins.

Source files:

Code, CSS, Images, Resources, …

GWT Compiler

Google Confidential and Proprietary

Optimize with Speed Tracer

14

Google Confidential and Proprietary

One click deploy to AppEngine

15

Google Confidential and Proprietary

Google APIs OverviewA brief introduction to Google APIs

16

Standard access to Google services

Google Confidential and Proprietary

Google APIs

17

Google Confidential and Proprietary

Google APIs

Standard access to Google services• Templates for expressing data

like JSON, XML, ...

• Flexible calling styles JSON-RPC and REST

• Configurable interceptors for common things authorization, caching, logging, ...

• Auto-generated client libraries Java, Python, JavaScript

18

Google Confidential and Proprietary

Google APIs

http://code.google.com/more/table/

19

Google Confidential and Proprietary

Google APIs

Many APIs available• Ads, Analytics, Apps, Books, Buzz, Calendar, Contacts, ...

http://code.google.com/more/

20

Google Confidential and Proprietary

Google API Documentation

Select an API and explore

21

Google Confidential and Proprietary

Google API Documentation

Documentation

Javadoc

22

http://code.google.com/apis/gdata/javadoc/

Google Confidential and Proprietary

Importing Google APIs

Import an API into your Eclipse project• Click on “Import Google APIs...”

• Select the desired API and click “Finish”

23

Import

GPE

Google Confidential and Proprietary

Google API Documentation (alternate)

Alternate path to documentation• Click on “Import Google APIs...”

• Click “API documentation”

24

GPE

Google Confidential and Proprietary

Book APIs

Java packages

• com.google.gdata.client.books.* BookService VolumeQuery

• com.google.gdata.data.books.* BooksCategory BooksLink BooksNamespace VolumeFeed VolumnEntry ...

25

Code to search book content ...

Google Confidential and Proprietary

Book Search Example

26

• Application name = [company-id]-[app-name]-[app-version]

Google Confidential and Proprietary

Initialize the service

27

• Book search URL

• Search text

• Only return results which have previews available

Google Confidential and Proprietary

Build the query

28

Unique to each service

• Search criteria

• Search result

Google Confidential and Proprietary

Execute the query

29

• Show the result to the user

Google Confidential and Proprietary

Display the result

30

Google Confidential and Proprietary

Other Google API resources

Samples• http://code.google.com/p/gdata-java-client/downloads/list

Other tools• http://code.google.com/apis/explorer/

• http://googlecodesamples.com/oauth_playground/

• http://code.google.com/apis/chart/docs/chart_playground.html

31

Google Confidential and Proprietary 32

Lab 1Command Line Book Search

Google Confidential and Proprietary

Course materials

All course materials are available on USB flash drive

Copy the following from the USB drive to your computer• Eclipse 3.6.2 (if you don’t already have it)

• gpe-2.3-alpha-eclipse3.6.zip

• gwt-tutorial.zip

33

Google Confidential and Proprietary

Installation

Unzip Eclipse 3.6.2

Install GPE 2.3 Alpha• Select “Help > Install New Software”• Click “Add”• Click “Archive”• Locate “gpe-2.3-alpha-eclipse3.6.zip”

Install GWT Tutorial• Repeat for “gwt-tutorial.zip”

Must have network connection

Calculating requirements takes time

34

Google Confidential and Proprietary

Load Lab

Select “Window > Show GWT Tutorial”

Select “Lab 1”

Click “Import” toolbar button

35

Google Confidential and Proprietary

Import Google APIs

Select “BookSearch” project

Click “Import Google APIs” toolbar button

Select “Books” and click “Finish”

36

Google Confidential and Proprietary

Edit Search

public static void main(String[] args) throws Exception { // Get the search text String searchText = "EclipseCon";

if (args != null && args.length > 0) { String firstArg = args[0]; if (firstArg != null) { firstArg = firstArg.trim(); if (firstArg.length() > 0) { searchText = firstArg; } } }

... etc ...

37

Modify the search term

BookSearchCmdLine.java

Google Confidential and Proprietary

Run

Right click on “BookSearchCmdLine” file

Select “Run As > Java Application”

38

Google Confidential and Proprietary 39

GWT OverviewA brief introduction to the Google Web Toolkit

Google Confidential and Proprietary

GWT in 10 seconds

40

AsynchronousJavaScriptAndXML++

Google Confidential and Proprietary

GWT overview

41

Java GWT Compiler

JavaScript(optimized)

Google Confidential and Proprietary

GWT overview

Advantages• Write web apps in Java

• Compiles to optimized JavaScript (small and fast)

• Easy (and efficient) RPC

• Open source compiler

• Cross browser support... just works

42

Plugins

Google Confidential and Proprietary

Can you find the bug?

43

Google Confidential and Proprietary

Catch errors at compile time

44

Google Confidential and Proprietary

Used at Google

45

AdWords, AdSense, Maps, Docs, Groups, ...

Google Confidential and Proprietary

Rich ecosystem

46

Utilities gwt-dnd, gwt-log, gwt-voices, gwt-fx

Mobile gwt-mobile-toolkit

Google Confidential and Proprietary

Rich ecosystem

www.gwtmarketplace.com

47

Google Confidential and Proprietary

GWT UI Gallery

48

Google Confidential and Proprietary

GWT and GPEGWT development with Google Plugin for Eclipse

49

Google Confidential and Proprietary

Creating a new GWT project

Click the “new web application” button and fill in the fields

50

Google Confidential and Proprietary

Importing Google APIs

Select a project and click “Import Google APIs” toolbar button

51

Google Confidential and Proprietary

Project structure

• Client code• Client only code• Restricted library• Java code compiled to JavaScript

• Server code• Server only code• Full Java library

• Shared code• Restricted library• Code available to both client and server

• Google APIs• Server only code

52

Google Confidential and Proprietary

UiBinder

File > New > Other...

53

Google Confidential and Proprietary

UiBinder

Associated source files• SearchPanel.ui.xml - layout

• SearchPanel.java - behavior

54

Google Confidential and Proprietary

UiBinder

55

<ui:UiBinder xmlns:ui="... etc ..."> <g:HTMLPanel width="600px" height="100%"> Please enter a search term: <g:AbsolutePanel width="600px" height="250px"> <g:at left="0" top="0"> <g:TextBox ui:field="searchText" ... >EclipseCon</g:TextBox> </g:at> <g:at left="514" top="0"> <g:Button ui:field="searchButton" ... >Search</g:Button> </g:at> <g:at left="0" top="27"> <g:ListBox ui:field="resultsList" ...="10"/> </g:at> </g:AbsolutePanel> ... etc ...

public class SearchPanel extends Composite { interface SearchPanelUiBinder extends UiBinder<Widget, SearchPanel> { } private static SearchPanelUiBinder uiBinder = GWT.create(SearchPanelUiBinder.class); @UiField TextBox searchText; @UiField Button searchButton; @UiField ListBox resultsList; ... @UiHandler("searchButton") void onSearchButtonClick(ClickEvent event) { search(); }

SearchPanel.ui.xml

SearchPanel.java

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

search(“some-search-text”)

BookSearchResult

56

Client Server

• Send / receive Plain Old Java Objects (POJO)

• Versioned to help keep client & server in sync

• Serialized, JSON, or XML data formats

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}

57

Client

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}

58

Client

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}

public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);}

59

Client

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}

public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);}

60

Client

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}

public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);

void search() { bookSearch.search(searchText.getText(), new AsyncCallback<BookSearchResult>() { public void onSuccess(BookSearchResult results) { // show search results } public void onFailure(Throwable caught) // report error to user } }); }}

61

Client

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public class BookSearchImpl extends RemoteServiceServlet implements BookSearch {

62

Server

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public class BookSearchImpl extends RemoteServiceServlet implements BookSearch {

public BookSearchResult search(String input) {

63

Server

Google Confidential and Proprietary

GWT RPC

@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}

public class BookSearchImpl extends RemoteServiceServlet implements BookSearch {

public BookSearchResult search(String input) {

... perform search ... // Return the result BookSearchResult result = new BookSearchResult(); result.setBooks(books.toArray(new Book[books.size()])); return result; }}

64

Server

Google Confidential and Proprietary

Lab 2GWT UI Book Search

65

Google Confidential and Proprietary

Load Lab

Select “Window > Show GWT Tutorial”

Select “Lab 2”

Click “Import” toolbar button

66

Google Confidential and Proprietary

Import Google APIs

Select “BookSearch” project

Click “Import Google APIs” toolbar button

Select “Books” and click “Finish”

67

Google Confidential and Proprietary

Edit UI

Double-click on “SearchPanel.ui.xml”

Click on “Design” tab

68

Google Confidential and Proprietary

Add Event Handler

Right-click on “resultList” widget

Select “Add Event Handler > onDoubleClick”

69

Google Confidential and Proprietary

Event Handler Behavior

Implement the event handler to open a new browser tab showing the content

70

Google Confidential and Proprietary

Event Handler Behavior

UI Element UI Event

@UiHandler("resultsList")void onResultsListDoubleClick(DoubleClickEvent event) { int index = resultsList.getSelectedIndex(); if (index != -1 && currentResults != null) { Book book = currentResults.getBooks()[index]; Window.open(book.getPreviewHref(), "_blank", ""); }}

Open new browser tab Get selected book

71

Google Confidential and Proprietary

Run

Right click on “BookSearch” project

Select “Run As > Web Application”

Opens “Development Mode” view

72

Google Confidential and Proprietary

Run

Double-click on URL in “Development Mode” view

Enter search term

Click “Search” button

73

Google Confidential and Proprietary

Check your work

Select “Lab 2 - GWT Book Search (complete)”

Click “Compare” toolbar button

74

Google Confidential and Proprietary

AdvancedAdvanced GWT Topics

75

Google Confidential and Proprietary

Optimize with Speed Tracer

Hooks in to low-level instrumentation in the browser to provide information about:• paint events

• CSS style recalculation

• layout events

• general DOM events

• network traffic

76

Google Confidential and Proprietary

Optimize with Speed Tracer

Why does such detailed information matter?• UIs are complex, and they take time to lay out - users can tell

• It’s easy to write pathological UI code and not know it

77

// This line invalidates layout.elementA.className = 'foo';

// This line requires layout to be up to date.var aWidth = elementA.offsetWidth;

// Invalidates layout again.elementB.className = 'bar';

// Requires layout to be up to datevar bWidth = elementB.offsetWidth;

Google Confidential and Proprietary

Optimize with Speed Tracer

Instead..

78

// These lines invalidate layout.elementA.className = 'foo';elementB.className = 'bar';

// This line requires layout to be up to date.var aWidth = elementA.offsetWidth;

// Layout is already up to date; nothing to dovar bWidth = elementB.offsetWidth;

Google Confidential and Proprietary

Launch SpeedTracer

From Chrome...

Or from Eclipse...

79

Google Confidential and Proprietary

ClientBundle

Ensures that an application’s resources are perfectly cacheable • the filename of the resource is based on a MD5 hash of the file’s contents

• configure your web server to cache files that match “*.cache.*” until the sun explodes

Reduces HTTP round-trips for resources• inline resources into compiled JS with data:// URLs

80

Without ClientBundle... slow to load

Google Confidential and Proprietary

A Few Resource Types..

TextResource• either intern strings into compiled JavaScript, or place all strings into a single

file that’s fetched at runtime

• @Source(“foo.txt”), textResource.getText()

CssResource • constants

In CSS: @def small 1px; border: small solid black; In Java: cssResource.small()

• conditional CSS compile-time: @if user.agent ie6 opera { // css rules } runtime: @if (com.module.Foo.staticBooleanFunction()) { // css rules }

• runtime substitution @eval userBackground com.module.UserPrefs.getUserBackground(); div

{ background: userBackground; }

• other cool stuff: minification, obfuscation, value functions, image spriting.. 81

Google Confidential and Proprietary

ImageResource in ClientBundle

82

∑ Separate Bundled

20,558 bytes

6,824 bytes

11 separate images

1 bundled image

Google Confidential and Proprietary

Code Splitting

Defer downloading portions of your application

83

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);  }}

Google Confidential and Proprietary

Code Splitting

Defer downloading portions of your application

84

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.runAsync(new RunAsyncCallback() {          public void onFailure(Throwable caught) {            Window.alert("Code download failed");          }

          public void onSuccess() {

          }        });

Google Confidential and Proprietary

Code Splitting

Very powerful tool for ...• reducing your application’s initial download size

• reducing startup time

Splitting your app effectively requires ...• tools - such as the compile report

• iteration - you won’t get it right the first time

85

Google Confidential and Proprietary

Compiler Optimizations

GWT Compiler automatically does...• Shrinking (obfuscation)

• Type tightening

• Dead code removal

• Inlining

• Constant folding

• Common subexpression elimination

86

Google Confidential and Proprietary

Compiler Options

-XdisableClassMetadata• Disables some java.lang.Class methods (e.g. getName())

-XdisableCastChecking• Disables run-time checking of cast operations

87

Google Confidential and Proprietary

RPC “flavors”

• RequestBuilder + JSONParser (see RESTY-GWT)

• RequestBuilder + XMLParser

• GWT-RPC (easiest) Requires Java on the server-side

• RequestFactory Also requires Java on the server-side higher level of abstraction over GWT-RPC only send data from server to client if that data has been modified since the last

request

None of the RPC mechanisms are synchronous!

88

Google Confidential and Proprietary

“Frameworks”

Model-View-Presenter• View: UI and implementation

• Presenter: business logic, formats the data for display in the view, sits between model and view

Activities and Places• Activity (presenter)

• Places (state in the UI, tied to browser history)

• A place is associated with an activity; an activity has an associated view

Cell Widgets• used for displaying large datasets quickly

• display is done using innerHTML instead of DOM manipulation

• data providers; updates to the data source are reflected in the widget

• can also accept input and push changes back to data source89

Google Confidential and Proprietary

Authorization

Need access to a user’s data? You need authorization from them.• Google APIs

Enter OAuth• allows you to write an application that asks a user’s permission to access a

protected resource (i.e. their gmail contacts)

• the user does two things: they first authenticate with the entity that controls the data (i.e. Google) the entity then asks the user if he/she wants to give your application to access a

specific set of your data; the user grants/denies permission

• if the user grants permission, your application receives a notification via a callback URL, along with a token that can be used to access the resource

• a scope is needed this is defined by the entity that controls the data

• your application never actually sees the user’s password!

90

Google Confidential and Proprietary

OAuth

Gotchas with OAuth• “dance”: request token, authorized token, access token

• user authentication with the entity happens in a web browser

• signed requests - the token, sent along with the request, is signed with a key based on the request URL (no curl!)

OAuth 2.0• no signed requests; all requests need to be done over HTTPs

• greatly simplifies the process

• access token and refresh token

91

Google Confidential and Proprietary

OAuth

Resources• Using OAuth 2.0 to Access Google APIs

http://code.google.com/apis/accounts/docs/OAuth2.html

• Using OAuth with the GData APIs http://code.google.com/apis/gdata/articles/oauth.html (these haven’t moved to OAuth 2.0 yet)

• OAuth 1.0 Playground http://googlecodesamples.com/oauth_playground/

• Authentication and Authorization for Google APIs http://code.google.com/apis/accounts/docs/GettingStarted.html

92

Google Confidential and Proprietary

Testing

• use GWTTestCase to test GWT UIs

• use MVP (not MVC) to isolate UI code and maximize testability

Google I/O talk on testing ...• http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.html

Testing methodologies ...• http://code.google.com/webtoolkit/articles/testing_methodologies_using_gwt.html

93

MVP

Plugins

MVC

Google Confidential and Proprietary

Questions

?94

?

?

?

Google Confidential and Proprietary

Thank You

Where to get it: http://code.google.com/webtoolkit/

Wiki, issue tracker, source: http://code.google.com/p/google-web-toolkit/

Official GWT blog: http://google-web-toolkit.blogspot.com/

95