95
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

Gwt app start to finish

Embed Size (px)

Citation preview

Page 1: Gwt app start to finish

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

Page 2: Gwt app start to finish

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

Page 3: Gwt app start to finish

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

Page 4: Gwt app start to finish

Google Confidential and Proprietary

Introduction

Rajeev Dayal

4

Eric Clayberg Dan Rubel

Page 5: Gwt app start to finish

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

Page 6: Gwt app start to finish

Google Confidential and Proprietary

GPE OverviewA brief introduction to Google Plugin for Eclipse

6

Page 7: Gwt app start to finish

Google Confidential and Proprietary

Google Plugin for Eclipse

7

GoogleAPIs

GPE

Page 8: Gwt app start to finish

Google Confidential and Proprietary

Google Plugin for Eclipse

Wizards, Quick Fixes, Launching, Optimization, Deployment

8

Page 9: Gwt app start to finish

Google Confidential and Proprietary

GWT Designer

Robust visual editing of GWT UI code

9

Page 10: Gwt app start to finish

Google Confidential and Proprietary

Development Cycle

10

HitRefresh

QuickTest

WriteCode

Page 11: Gwt app start to finish

Google Confidential and Proprietary

GPE Dev Mode

11

Page 12: Gwt app start to finish

Google Confidential and Proprietary

Debug in GPE Dev Mode

12

Page 13: Gwt app start to finish

Google Confidential and Proprietary

Compile for production

13

Your app running here.No plugins.

Source files:

Code, CSS, Images, Resources, …

GWT Compiler

Page 14: Gwt app start to finish

Google Confidential and Proprietary

Optimize with Speed Tracer

14

Page 15: Gwt app start to finish

Google Confidential and Proprietary

One click deploy to AppEngine

15

Page 16: Gwt app start to finish

Google Confidential and Proprietary

Google APIs OverviewA brief introduction to Google APIs

16

Page 17: Gwt app start to finish

Standard access to Google services

Google Confidential and Proprietary

Google APIs

17

Page 18: Gwt app start to finish

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

Page 19: Gwt app start to finish

Google Confidential and Proprietary

Google APIs

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

19

Page 20: Gwt app start to finish

Google Confidential and Proprietary

Google APIs

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

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

20

Page 21: Gwt app start to finish

Google Confidential and Proprietary

Google API Documentation

Select an API and explore

21

Page 22: Gwt app start to finish

Google Confidential and Proprietary

Google API Documentation

Documentation

Javadoc

22

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

Page 23: Gwt app start to finish

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

Page 24: Gwt app start to finish

Google Confidential and Proprietary

Google API Documentation (alternate)

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

• Click “API documentation”

24

GPE

Page 25: Gwt app start to finish

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

Page 26: Gwt app start to finish

Code to search book content ...

Google Confidential and Proprietary

Book Search Example

26

Page 27: Gwt app start to finish

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

Google Confidential and Proprietary

Initialize the service

27

Page 28: Gwt app start to finish

• Book search URL

• Search text

• Only return results which have previews available

Google Confidential and Proprietary

Build the query

28

Unique to each service

Page 29: Gwt app start to finish

• Search criteria

• Search result

Google Confidential and Proprietary

Execute the query

29

Page 30: Gwt app start to finish

• Show the result to the user

Google Confidential and Proprietary

Display the result

30

Page 31: Gwt app start to finish

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

Page 32: Gwt app start to finish

Google Confidential and Proprietary 32

Lab 1Command Line Book Search

Page 33: Gwt app start to finish

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

Page 34: Gwt app start to finish

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

Page 35: Gwt app start to finish

Google Confidential and Proprietary

Load Lab

Select “Window > Show GWT Tutorial”

Select “Lab 1”

Click “Import” toolbar button

35

Page 36: Gwt app start to finish

Google Confidential and Proprietary

Import Google APIs

Select “BookSearch” project

Click “Import Google APIs” toolbar button

Select “Books” and click “Finish”

36

Page 37: Gwt app start to finish

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

Page 38: Gwt app start to finish

Google Confidential and Proprietary

Run

Right click on “BookSearchCmdLine” file

Select “Run As > Java Application”

38

Page 39: Gwt app start to finish

Google Confidential and Proprietary 39

GWT OverviewA brief introduction to the Google Web Toolkit

Page 40: Gwt app start to finish

Google Confidential and Proprietary

GWT in 10 seconds

40

AsynchronousJavaScriptAndXML++

Page 41: Gwt app start to finish

Google Confidential and Proprietary

GWT overview

41

Java GWT Compiler

JavaScript(optimized)

Page 42: Gwt app start to finish

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

Page 43: Gwt app start to finish

Google Confidential and Proprietary

Can you find the bug?

43

Page 44: Gwt app start to finish

Google Confidential and Proprietary

Catch errors at compile time

44

Page 45: Gwt app start to finish

Google Confidential and Proprietary

Used at Google

45

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

Page 46: Gwt app start to finish

Google Confidential and Proprietary

Rich ecosystem

46

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

Mobile gwt-mobile-toolkit

Page 47: Gwt app start to finish

Google Confidential and Proprietary

Rich ecosystem

www.gwtmarketplace.com

47

Page 48: Gwt app start to finish

Google Confidential and Proprietary

GWT UI Gallery

48

Page 49: Gwt app start to finish

Google Confidential and Proprietary

GWT and GPEGWT development with Google Plugin for Eclipse

49

Page 50: Gwt app start to finish

Google Confidential and Proprietary

Creating a new GWT project

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

50

Page 51: Gwt app start to finish

Google Confidential and Proprietary

Importing Google APIs

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

51

Page 52: Gwt app start to finish

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

Page 53: Gwt app start to finish

Google Confidential and Proprietary

UiBinder

File > New > Other...

53

Page 54: Gwt app start to finish

Google Confidential and Proprietary

UiBinder

Associated source files• SearchPanel.ui.xml - layout

• SearchPanel.java - behavior

54

Page 55: Gwt app start to finish

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

Page 56: Gwt app start to finish

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

Page 57: Gwt app start to finish

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

Page 58: Gwt app start to finish

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

Page 59: Gwt app start to finish

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

Page 60: Gwt app start to finish

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

Page 61: Gwt app start to finish

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

Page 62: Gwt app start to finish

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

Page 63: Gwt app start to finish

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

Page 64: Gwt app start to finish

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

Page 65: Gwt app start to finish

Google Confidential and Proprietary

Lab 2GWT UI Book Search

65

Page 66: Gwt app start to finish

Google Confidential and Proprietary

Load Lab

Select “Window > Show GWT Tutorial”

Select “Lab 2”

Click “Import” toolbar button

66

Page 67: Gwt app start to finish

Google Confidential and Proprietary

Import Google APIs

Select “BookSearch” project

Click “Import Google APIs” toolbar button

Select “Books” and click “Finish”

67

Page 68: Gwt app start to finish

Google Confidential and Proprietary

Edit UI

Double-click on “SearchPanel.ui.xml”

Click on “Design” tab

68

Page 69: Gwt app start to finish

Google Confidential and Proprietary

Add Event Handler

Right-click on “resultList” widget

Select “Add Event Handler > onDoubleClick”

69

Page 70: Gwt app start to finish

Google Confidential and Proprietary

Event Handler Behavior

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

70

Page 71: Gwt app start to finish

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

Page 72: Gwt app start to finish

Google Confidential and Proprietary

Run

Right click on “BookSearch” project

Select “Run As > Web Application”

Opens “Development Mode” view

72

Page 73: Gwt app start to finish

Google Confidential and Proprietary

Run

Double-click on URL in “Development Mode” view

Enter search term

Click “Search” button

73

Page 74: Gwt app start to finish

Google Confidential and Proprietary

Check your work

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

Click “Compare” toolbar button

74

Page 75: Gwt app start to finish

Google Confidential and Proprietary

AdvancedAdvanced GWT Topics

75

Page 76: Gwt app start to finish

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

Page 77: Gwt app start to finish

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;

Page 78: Gwt app start to finish

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;

Page 79: Gwt app start to finish

Google Confidential and Proprietary

Launch SpeedTracer

From Chrome...

Or from Eclipse...

79

Page 80: Gwt app start to finish

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

Page 81: Gwt app start to finish

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

Page 82: Gwt app start to finish

Google Confidential and Proprietary

ImageResource in ClientBundle

82

∑ Separate Bundled

20,558 bytes

6,824 bytes

11 separate images

1 bundled image

Page 83: Gwt app start to finish

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

Page 84: Gwt app start to finish

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() {

          }        });

Page 85: Gwt app start to finish

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

Page 86: Gwt app start to finish

Google Confidential and Proprietary

Compiler Optimizations

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

• Type tightening

• Dead code removal

• Inlining

• Constant folding

• Common subexpression elimination

86

Page 87: Gwt app start to finish

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

Page 88: Gwt app start to finish

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

Page 89: Gwt app start to finish

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

Page 90: Gwt app start to finish

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

Page 91: Gwt app start to finish

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

Page 92: Gwt app start to finish

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

Page 93: Gwt app start to finish

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

Page 94: Gwt app start to finish

Google Confidential and Proprietary

Questions

?94

?

?

?

Page 95: Gwt app start to finish

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