Gwt app start to finish

2,657 views

Published on

Presented at EclipseCon 2011

Published in: Technology, News & Politics
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,657
On SlideShare
0
From Embeds
0
Number of Embeds
192
Actions
Shares
0
Downloads
86
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Gwt app start to finish

  1. 1. Course materialsAll course materials are available on USB flash driveCopy 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.zipInstall zipped update sites now to save time in Lab 1 Google Confidential and Proprietary 1
  2. 2. Client LogoGWT App start to finishA hands-on tutorial building GWT using GPEPresented by:Rajeev DayalEric ClaybergDan Rubel Google Confidential and Proprietary 2
  3. 3. AgendaIntroductionGPE OverviewGoogle APIsLab 1GWT OverviewGWT and GPELab 2 GWT = Google Web ToolkitAdvanced Topics GPE = Google Plugin for Eclipse Google Confidential and Proprietary 3
  4. 4. IntroductionRajeev Dayal Eric Clayberg Dan Rubel Google Confidential and Proprietary 4
  5. 5. Course materialsAll course materials are available on USB flash driveCopy 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.zipInstall zipped update sites now to save time in Lab 1 Google Confidential and Proprietary 5
  6. 6. GPE OverviewA brief introduction to Google Plugin for Eclipse Google Confidential and Proprietary 6
  7. 7. Google Plugin for Eclipse Google APIs GPE Google Confidential and Proprietary 7
  8. 8. Google Plugin for EclipseWizards, Quick Fixes, Launching, Optimization, Deployment Google Confidential and Proprietary 8
  9. 9. GWT DesignerRobust visual editing of GWT UI code Google Confidential and Proprietary 9
  10. 10. Development Cycle Write Hit Code Refresh Quick Test Google Confidential and Proprietary 10
  11. 11. GPE Dev Mode Google Confidential and Proprietary 11
  12. 12. Debug in GPE Dev Mode Google Confidential and Proprietary 12
  13. 13. Compile for production Source files: Code, CSS, Images, Resources, … GWT Compiler Your app running here. No plugins. Google Confidential and Proprietary 13
  14. 14. Optimize with Speed Tracer Google Confidential and Proprietary 14
  15. 15. One click deploy to AppEngine Google Confidential and Proprietary 15
  16. 16. Google APIs OverviewA brief introduction to Google APIs Google Confidential and Proprietary 16
  17. 17. Google APIsStandard access to Google services Google Confidential and Proprietary 17
  18. 18. Google APIsStandard 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 Google Confidential and Proprietary 18
  19. 19. Google APIshttp://code.google.com/more/table/ Google Confidential and Proprietary 19
  20. 20. Google APIsMany APIs available• Ads, Analytics, Apps, Books, Buzz, Calendar, Contacts, ...http://code.google.com/more/ Google Confidential and Proprietary 20
  21. 21. Google API DocumentationSelect an APIand explore Google Confidential and Proprietary 21
  22. 22. Google API DocumentationDocumentationJavadoc http://code.google.com/apis/gdata/javadoc/ Google Confidential and Proprietary 22
  23. 23. Importing Google APIsImport an API into your Eclipse project• Click on “Import Google APIs...”• Select the desired API and click “Finish” GPE Import Google Confidential and Proprietary 23
  24. 24. Google API Documentation (alternate)Alternate path to documentation• Click on “Import Google APIs...”• Click “API documentation” GPE Google Confidential and Proprietary 24
  25. 25. Book APIsJava packages• com.google.gdata.client.books.*  BookService  VolumeQuery• com.google.gdata.data.books.*  BooksCategory  BooksLink  BooksNamespace  VolumeFeed  VolumnEntry  ... Google Confidential and Proprietary 25
  26. 26. Book Search ExampleCode to search book content ... Google Confidential and Proprietary 26
  27. 27. Initialize the service• Application name = [company-id]-[app-name]-[app-version] Google Confidential and Proprietary 27
  28. 28. Build the query• Book search URL Unique to each service• Search text• Only return results which have previews available Google Confidential and Proprietary 28
  29. 29. Execute the query• Search criteria• Search result Google Confidential and Proprietary 29
  30. 30. Display the result• Show the result to the user Google Confidential and Proprietary 30
  31. 31. Other Google API resourcesSamples• http://code.google.com/p/gdata-java-client/downloads/listOther tools• http://code.google.com/apis/explorer/• http://googlecodesamples.com/oauth_playground/• http://code.google.com/apis/chart/docs/chart_playground.html Google Confidential and Proprietary 31
  32. 32. Lab 1Command Line Book Search Google Confidential and Proprietary 32
  33. 33. Course materialsAll course materials are available on USB flash driveCopy 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 Google Confidential and Proprietary 33
  34. 34. InstallationUnzip Eclipse 3.6.2Install 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 connectionCalculating requirements takes time Google Confidential and Proprietary 34
  35. 35. Load LabSelect “Window > Show GWT Tutorial”Select “Lab 1”Click “Import” toolbar button Google Confidential and Proprietary 35
  36. 36. Import Google APIsSelect “BookSearch” projectClick “Import Google APIs” toolbar buttonSelect “Books” and click “Finish” Google Confidential and Proprietary 36
  37. 37. Edit Search BookSearchCmdLine.javapublic static void main(String[] args) throws Exception { // Get the search text String searchText = "EclipseCon"; Modify the search term if (args != null && args.length > 0) { String firstArg = args[0]; if (firstArg != null) { firstArg = firstArg.trim(); if (firstArg.length() > 0) { searchText = firstArg; } } } ... etc ... Google Confidential and Proprietary 37
  38. 38. RunRight click on “BookSearchCmdLine” fileSelect “Run As > Java Application” Google Confidential and Proprietary 38
  39. 39. GWT OverviewA brief introduction to the Google Web Toolkit Google Confidential and Proprietary 39
  40. 40. GWT in 10 seconds Asynchronous JavaScript And XML++ Google Confidential and Proprietary 40
  41. 41. GWT overview Java GWT Compiler JavaScript (optimized) Google Confidential and Proprietary 41
  42. 42. GWT overviewAdvantages• Write web apps in Java• Compiles to optimized JavaScript (small and fast)• Easy (and efficient) RPC• Open source compiler• Cross browser support... just works Plugins Google Confidential and Proprietary 42
  43. 43. Can you find the bug? Google Confidential and Proprietary 43
  44. 44. Catch errors at compile time Google Confidential and Proprietary 44
  45. 45. Used at Google AdWords, AdSense, Maps, Docs, Groups, ... Google Confidential and Proprietary 45
  46. 46. Rich ecosystemUtilities gwt-dnd, gwt-log, gwt-voices, gwt-fxMobile gwt-mobile-toolkit Google Confidential and Proprietary 46
  47. 47. Rich ecosystemwww.gwtmarketplace.com Google Confidential and Proprietary 47
  48. 48. GWT UI Gallery Google Confidential and Proprietary 48
  49. 49. GWT and GPEGWT development with Google Plugin for Eclipse Google Confidential and Proprietary 49
  50. 50. Creating a new GWT projectClick the “new web application” button and fill in the fields Google Confidential and Proprietary 50
  51. 51. Importing Google APIsSelect a project and click “Import Google APIs” toolbar button Google Confidential and Proprietary 51
  52. 52. 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 Google Confidential and Proprietary 52
  53. 53. UiBinderFile > New > Other... Google Confidential and Proprietary 53
  54. 54. UiBinderAssociated source files• SearchPanel.ui.xml - layout• SearchPanel.java - behavior Google Confidential and Proprietary 54
  55. 55. UiBinder<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 ... SearchPanel.ui.xmlpublic class SearchPanel extends Composite { SearchPanel.java 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(); } Google Confidential and Proprietary 55
  56. 56. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);} search(“some-search-text”)Client Server BookSearchResult• 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 56
  57. 57. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Clientpublic interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);} Google Confidential and Proprietary 57
  58. 58. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Clientpublic interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);} Google Confidential and Proprietary 58
  59. 59. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Clientpublic interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);} Google Confidential and Proprietary 59
  60. 60. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Clientpublic interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);} Google Confidential and Proprietary 60
  61. 61. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Clientpublic 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 } }); }} Google Confidential and Proprietary 61
  62. 62. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Serverpublic class BookSearchImpl extends RemoteServiceServlet implements BookSearch { Google Confidential and Proprietary 62
  63. 63. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Serverpublic class BookSearchImpl extends RemoteServiceServlet implements BookSearch { public BookSearchResult search(String input) { Google Confidential and Proprietary 63
  64. 64. GWT RPC@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}Serverpublic 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; }} Google Confidential and Proprietary 64
  65. 65. Lab 2GWT UI Book Search Google Confidential and Proprietary 65
  66. 66. Load LabSelect “Window > Show GWT Tutorial”Select “Lab 2”Click “Import” toolbar button Google Confidential and Proprietary 66
  67. 67. Import Google APIsSelect “BookSearch” projectClick “Import Google APIs” toolbar buttonSelect “Books” and click “Finish” Google Confidential and Proprietary 67
  68. 68. Edit UIDouble-click on “SearchPanel.ui.xml”Click on “Design” tab Google Confidential and Proprietary 68
  69. 69. Add Event HandlerRight-click on “resultList” widgetSelect “Add Event Handler > onDoubleClick” Google Confidential and Proprietary 69
  70. 70. Event Handler BehaviorImplement the event handlerto open a new browser tab showing the content Google Confidential and Proprietary 70
  71. 71. 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 Google Confidential and Proprietary 71
  72. 72. RunRight click on “BookSearch” projectSelect “Run As > Web Application” Opens “Development Mode” view Google Confidential and Proprietary 72
  73. 73. RunDouble-click on URL in “Development Mode” viewEnter search termClick “Search” button Google Confidential and Proprietary 73
  74. 74. Check your workSelect “Lab 2 - GWT Book Search (complete)”Click “Compare” toolbar button Google Confidential and Proprietary 74
  75. 75. AdvancedAdvanced GWT Topics Google Confidential and Proprietary 75
  76. 76. Optimize with Speed TracerHooks in to low-level instrumentation in the browser to provideinformation about:• paint events• CSS style recalculation• layout events• general DOM events• network traffic Google Confidential and Proprietary 76
  77. 77. Optimize with Speed TracerWhy 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 // 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 date var bWidth = elementB.offsetWidth; Google Confidential and Proprietary 77
  78. 78. Optimize with Speed TracerInstead.. // 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 do var bWidth = elementB.offsetWidth; Google Confidential and Proprietary 78
  79. 79. Launch SpeedTracerFrom Chrome...Or from Eclipse... Google Confidential and Proprietary 79
  80. 80. ClientBundleEnsures 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 explodesReduces HTTP round-trips for resources• inline resources into compiled JS with data:// URLsWithout ClientBundle... slow to load Google Confidential and Proprietary 80
  81. 81. 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.. Google Confidential and Proprietary 81
  82. 82. ImageResource in ClientBundle 20,558 bytes 11 separate images 6,824 bytes 1 bundled image ∑ Separate Bundled Google Confidential and Proprietary 82
  83. 83. Code SplittingDefer downloading portions of your application 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 83
  84. 84. Code SplittingDefer downloading portions of your application public class Hello implements EntryPoint {   public void onModuleLoad() {     Button b = new Button("Click me", new ClickHandler() {       public void onClick(ClickEvent event) {         GWT.runAsync(new RunAsyncCallback() {           public void onFailure(Throwable caught) {             Window.alert("Code download failed");           }           public void onSuccess() {             Window.alert("Hello, AJAX");           }         });       }     });     RootPanel.get().add(b);   } } Google Confidential and Proprietary 84
  85. 85. Code SplittingVery powerful tool for ...• reducing your application’s initial download size• reducing startup timeSplitting your app effectively requires ...• tools - such as the compile report• iteration - you won’t get it right the first time Google Confidential and Proprietary 85
  86. 86. Compiler OptimizationsGWT Compiler automatically does...• Shrinking (obfuscation)• Type tightening• Dead code removal• Inlining• Constant folding• Common subexpression elimination Google Confidential and Proprietary 86
  87. 87. Compiler Options-XdisableClassMetadata• Disables some java.lang.Class methods (e.g. getName())-XdisableCastChecking• Disables run-time checking of cast operations Google Confidential and Proprietary 87
  88. 88. 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 requestNone of the RPC mechanisms are synchronous! Google Confidential and Proprietary 88
  89. 89. “Frameworks”Model-View-Presenter• View: UI and implementation• Presenter: business logic, formats the data for display in the view, sits between model and viewActivities 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 viewCell 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 source Confidential and Proprietary Google 89
  90. 90. AuthorizationNeed access to a user’s data? You need authorization from them.• Google APIsEnter 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! Google Confidential and Proprietary 90
  91. 91. OAuthGotchas 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 Google Confidential and Proprietary 91
  92. 92. OAuthResources• 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 Google Confidential and Proprietary 92
  93. 93. Testing• use GWTTestCase to test GWT UIs• use MVP (not MVC) to isolate UI code and maximize testability MVP MVCGoogle I/O talk on testing ...• http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.htmlTesting methodologies ...• http://code.google.com/webtoolkit/articles/testing_methodologies_using_gwt.html Plugins Google Confidential and Proprietary 93
  94. 94. Questions ? ? ? ? Google Confidential and Proprietary 94
  95. 95. Thank YouWhere 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/ Google Confidential and Proprietary 95

×