YA GWT O GOOGLE WEB TOOLKIT
YA GWT O GOOGLE WEB TOOLKIT
RIA? RICH INTERNET APPLICATION UNA NUOVA USER EXPERIENCE!
Problematiche Gli sviluppatori possono impiegare anche il 90% del loro tempo per: <ul><ul><li>problemi di compatibilità tr...
mantenere molto codice Javascript
gestire il ciclo di vita del software
utilizzare correttamente AJAX </li></ul></ul>
La risposta è GWT Cosa non saranno più nostre preoccupazioni?  <ul><ul><li>incompatibilità tra i browser
gestione corretta della history del browser
localizzazione senza refresh della pagina
offuscamento del codice
riduzione del codice
image bundle </li></ul></ul>  in poche parole OTTIMIZZAZIONE
GWT = JAVA TO JAVASCRIPT Perchè Java? Una sola risposta: TOOL
GWT contro tutti VS.
Hello JUG! applicationCreator it.pronetics.gwt. client .HelloJUGApp  
Moduli *.gwt.xml In GWT è possibile definire dei  moduli . Ogni modulo è configurato in un file  con estensione:   gwt.xml...
Tags *.gwt.xml <inherits name=&quot;logical-module-name&quot; /> : Per importare altri moduli   <entry-point class=&quot;c...
Creare moduli esterni <ul><ul><li>I  moduli esterni  stanno a  GWT   come le  librerie  a  Java
Hanno in comune l'estensione  JAR
Il nostro progetto li può includere tramite il tag  inherits . Nelle prossime slide useremo:  </li></ul></ul><ul><ul><ul><...
<inherits name=&quot;com.google.gwt.http.HTTP&quot; /> </li></ul></ul></ul><ul><ul><li>Il jar deve avere la seguente  stru...
it/pronetics/module/client/.../*.java
it/pronetics/module/client/.../*.class </li></ul></ul></ul><ul><ul><li>il package client è obbligatorio, se ne usiamo uno ...
EntryPoint <ul><ul><li>Le classi definite come EntryPoint devono implementare l'omonima interfaccia e definire il metodo p...
RootPanel rappresenta, nella pagina, il contenitore di più alto livello (body html o un elemento div da noi definito). Per...
Vi ricordate Swing?
Hello JUG! ./HelloJUG-shell
Ecco il codice!   public void  onModuleLoad() { Image img =  new  Image( &quot;http://code.google.com/webtoolkit/logo-185x...
Architettura classica
Remote Procedure Call Una Remote Procedure Call è una funzione implementata lato server invocata dal client.   GWT RPC NON...
RPC gwt.xml   Nel nostro file gwt.xml dovremmo configurare la classe che implementa il servizio lato server.   Dobbiamo ma...
RPC diagrama del'interazione Cosa ci serve? <ul><li>L'interfaccia del servizio  MyService
L'interfaccia  MyServiceAsync
L'implementazione lato server  MyServiceImpl   </li></ul>
RPC interfaccie package it.jk.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.clie...
RPC Server package it.jk.server; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; import com.google.gwt.us...
RPC Client private   void  getVisitorInfo(String userName) {         // Iniziallizza il proxy per il servizio          if ...
Screenshot esempio RPC  
Maven?   Archetype per la generazione del progetto mvn archetype:create -DarchetypeGroupId=com.totsp.gwt  -DarchetypeArtif...
Generazione automatica file WAR
Gestione dipendenze
Scarica in automatico GWT da un repository di Maven </li></ul>
Flickr Mash-up Miliardi di informazioni sparse per la rete   Fare un applicativo Mash-up vuol dire sviluppare  un software...
Ringraziamo le API...                 ...e vediamo quelle che usa Flickr http://www.flickr.com/services/api/   REST  +  JSON
Prima prova di contatto... String url =  &quot; http://www.flickr.com/services/rest/?format=json& method =flickr.interesti...
...ma non funziona AJAX  non permette richieste CROSS-SITE  Questo a causa del principio di sicurezza SOP (same origin pol...
Ok, imbrogliamo! L'output dei servizi REST+JSON di Flickr (ma anche Google e altri) può avvenire in due modi:   <ul><ul><l...
  myCallbackFunction ({&quot;photos&quot;: {&quot;page&quot;:1, &quot;pages&quot;:5, &quot;perpage&quot;:100, &quot;total&...
Upcoming SlideShare
Loading in …5
×

Yagwto

1,413 views
1,347 views

Published on

by Davide Cerbo e Stefano Linguerri

La programmazione web sta facendo passi da gigante e oggi l’utente si aspetta che l’esperienza di utilizzo si avvicini sempre di più a quella a cui è abituato nei classici applicativi desktop. Il mondo degli sviluppatori ha risposto inventanto una nuova sigla: RIA, cioè Rich Internet Application. Google non è stata a guardare e ha fornito la sua risposta a questa esigenza donando alla community Google Web Toolkit. Questo nuovo framework permette di sviluppare in Java tutta l’interfaccia utente per poi ottenere un codice javascript che funzionerà su qualsiasi browser web senza l’installazione di plugin aggiuntivi. In questa presentazione vedremo:

* perchè sviluppare applicazioni RIA
* perchè usare GWT
* come GWT utilizza AJAX per comunicare con il server
* le ottimizzazione che avremo utilizzando GWT
* come uscire dal browser con Google Gear e Mozilla Prism
* e non solo…

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

No Downloads
Views
Total views
1,413
On SlideShare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
19
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • Yagwto

    1. 1. YA GWT O GOOGLE WEB TOOLKIT
    2. 2. YA GWT O GOOGLE WEB TOOLKIT
    3. 3. RIA? RICH INTERNET APPLICATION UNA NUOVA USER EXPERIENCE!
    4. 4. Problematiche Gli sviluppatori possono impiegare anche il 90% del loro tempo per: <ul><ul><li>problemi di compatibilità tra i browser
    5. 5. mantenere molto codice Javascript
    6. 6. gestire il ciclo di vita del software
    7. 7. utilizzare correttamente AJAX </li></ul></ul>
    8. 8. La risposta è GWT Cosa non saranno più nostre preoccupazioni? <ul><ul><li>incompatibilità tra i browser
    9. 9. gestione corretta della history del browser
    10. 10. localizzazione senza refresh della pagina
    11. 11. offuscamento del codice
    12. 12. riduzione del codice
    13. 13. image bundle </li></ul></ul>  in poche parole OTTIMIZZAZIONE
    14. 14. GWT = JAVA TO JAVASCRIPT Perchè Java? Una sola risposta: TOOL
    15. 15. GWT contro tutti VS.
    16. 16. Hello JUG! applicationCreator it.pronetics.gwt. client .HelloJUGApp  
    17. 17. Moduli *.gwt.xml In GWT è possibile definire dei moduli . Ogni modulo è configurato in un file con estensione: gwt.xml     < module >     < inherits name =&quot;com.google.gwt.user.User&quot;/>     < entry-point class =&quot;com.example.foo.MyModule&quot;/>  </ module >   Qui definiamo l'entry-point MyModule che sarà il &quot;main&quot; del nostro applicativo
    18. 18. Tags *.gwt.xml <inherits name=&quot;logical-module-name&quot; /> : Per importare altri moduli   <entry-point class=&quot;classname&quot; /> : La classe entry point dell'applicazione   <source path=&quot;path&quot; //> : Definisce in quale package riesodo i sorgenti della parte client, per default il package è client <public path=&quot;path&quot;/> : Il percorso dove risiedono le componenti statiche e componenti di terze parti (javascript, html, immagini, etc, etc).   <servlet path=&quot;url-path&quot; class=&quot;classname&quot;/> : Definisce il componente lato server per le chiamate RPC.   <script src=&quot;js-url&quot;/>,<stylesheet src=&quot;css-url&quot;/> : Per includere javascript e css   <extend-property name=&quot;client-property-name&quot; values=&quot;comma-separated-values&quot;/> : Per aggiungere delle proprietà
    19. 19. Creare moduli esterni <ul><ul><li>I moduli esterni stanno a GWT   come le librerie a Java
    20. 20. Hanno in comune l'estensione JAR
    21. 21. Il nostro progetto li può includere tramite il tag inherits . Nelle prossime slide useremo: </li></ul></ul><ul><ul><ul><li><inherits name=&quot;com.google.gwt.json.JSON&quot; />
    22. 22. <inherits name=&quot;com.google.gwt.http.HTTP&quot; /> </li></ul></ul></ul><ul><ul><li>Il jar deve avere la seguente struttura : </li></ul></ul><ul><ul><ul><li>it/pronetics/module/Test.gwt.xml
    23. 23. it/pronetics/module/client/.../*.java
    24. 24. it/pronetics/module/client/.../*.class </li></ul></ul></ul><ul><ul><li>il package client è obbligatorio, se ne usiamo uno diverso lo dobbiamo specificare tramite il tag source : </li></ul></ul><ul><ul><ul><li><source path=&quot;util&quot; /> </li></ul></ul></ul>
    25. 25. EntryPoint <ul><ul><li>Le classi definite come EntryPoint devono implementare l'omonima interfaccia e definire il metodo public void onModuleLoad() Questo è il metodo che viene invocato quando viene richiesta la url dell'entry point dell'applicazione per la prima volta.
    26. 26. RootPanel rappresenta, nella pagina, il contenitore di più alto livello (body html o un elemento div da noi definito). Per aggiungere elementi a RootPanel è sufficente chiamare: </li></ul></ul>       RootPanel.get().add(myPanel);
    27. 27. Vi ricordate Swing?
    28. 28. Hello JUG! ./HelloJUG-shell
    29. 29. Ecco il codice!   public void onModuleLoad() { Image img = new Image( &quot;http://code.google.com/webtoolkit/logo-185x175.png&quot; ); Button button = new Button( &quot;Click me&quot; ); ... VerticalPanel vPanel = new VerticalPanel(); ... vPanel.add(button); // Add image and button to the RootPanel RootPanel.get().add(vPanel); // Create the dialog box final DialogBox dialogBox = new DialogBox(); dialogBox.setText( &quot;Welcome to GWT!&quot; ); dialogBox.setAnimationEnabled(true); Button closeButton = new Button( &quot;close&quot; ); VerticalPanel dialogVPanel = new VerticalPanel(); ... closeButton.addClickListener( new ClickListener() { public void onClick(Widget sender) { dialogBox.hide(); } }); dialogBox.setWidget(dialogVPanel); button.addClickListener( new ClickListener() { public void onClick(Widget sender) { dialogBox.center(); dialogBox.show(); } }); } }
    30. 30. Architettura classica
    31. 31. Remote Procedure Call Una Remote Procedure Call è una funzione implementata lato server invocata dal client.   GWT RPC NON è la stessa tecnologia su cui sono basati i web services SOAP o REST .
    32. 32. RPC gwt.xml   Nel nostro file gwt.xml dovremmo configurare la classe che implementa il servizio lato server.   Dobbiamo mappare inoltre anche la path alla quale tale implementazione risponderà   ... <servlet path=&quot; /countVisitors &quot;  class=&quot; it.jk.server.VisitorsCountServiceImpl &quot;/> ...
    33. 33. RPC diagrama del'interazione Cosa ci serve? <ul><li>L'interfaccia del servizio MyService
    34. 34. L'interfaccia MyServiceAsync
    35. 35. L'implementazione lato server MyServiceImpl </li></ul>
    36. 36. RPC interfaccie package it.jk.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;   @RemoteServiceRelativePath(&quot;countVisitors&quot;) public interface VisitorsCountService extends RemoteService {     public String getVisitors (String name); } package it.jk.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; import com.google.gwt.user.client.rpc.AsyncCallback; public interface VisitorsCountServiceAsync {     void getVisitors (String name, AsyncCallback async); }
    37. 37. RPC Server package it.jk.server; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import it.jk.client.VisitorsCountService; @RemoteServiceRelativePath(&quot;countVisitors&quot;) public class VisitorsCountServiceImpl extends RemoteServiceServlet implements VisitorsCountService {     public String getVisitors (String name) {         VISITORS++;         return &quot;Ciao &quot; + name + &quot; è il click numero &quot; + VISITORS;     }     private static int VISITORS = 0; }
    38. 38. RPC Client private void getVisitorInfo(String userName) {         // Iniziallizza il proxy per il servizio         if (visitorCountService == null) {             visitorCountService = GWT.create(VisitorsCountService.class) ;         }         // Prepara l'ogetto per la callback         AsyncCallback <String> callback = new AsyncCallback <String>() {             public void onFailure(Throwable caught) {                 // TODO: Gestione errore             }             public void onSuccess(String result) {                 salutoLabel.setText(result);             }         };         // Chiama il metodo per sapere quante visite ci sono state         visitorCountService.getVisitors(userName, callback);     }
    39. 39. Screenshot esempio RPC  
    40. 40. Maven?   Archetype per la generazione del progetto mvn archetype:create -DarchetypeGroupId=com.totsp.gwt -DarchetypeArtifactId=maven-googlewebtoolkit2-archetype -DarchetypeVersion=1.0.4 -DremoteRepositories=http://gwt-maven.googlecode.com/svn/trunk/mavenrepo -DgroupId=myGroupId -DartifactId=myArtifactId Comando per eseguire l'applicazione mvn com.totsp.gwt:maven-googlewebtoolkit2-plugin:gwt Vantaggi <ul><li>Compila anche la componente lato server
    41. 41. Generazione automatica file WAR
    42. 42. Gestione dipendenze
    43. 43. Scarica in automatico GWT da un repository di Maven </li></ul>
    44. 44. Flickr Mash-up Miliardi di informazioni sparse per la rete   Fare un applicativo Mash-up vuol dire sviluppare  un software capace di aggregarle in un solo punto
    45. 45. Ringraziamo le API...                 ...e vediamo quelle che usa Flickr http://www.flickr.com/services/api/   REST + JSON
    46. 46. Prima prova di contatto... String url =  &quot; http://www.flickr.com/services/rest/?format=json& method =flickr.interestingness.getList& api_key =a1234567a1ce1bd1aba1234 aaec123e1& user_id =1234567@N01 &quot;; RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, apiUrl); Request req = builder.sendRequest(null, new JsonRequestCallBack());     public class JsonRequestCallBack implements RequestCallback {      public void onError(Request request, Throwable exception) {             //gestisco richiesta in errore          }          public void onResponseReceived(Request req, Response response) {             //gestisco richiesta avvenuta con successo         } }        
    47. 47. ...ma non funziona AJAX non permette richieste CROSS-SITE Questo a causa del principio di sicurezza SOP (same origin policy) Abbiamo 3 soluzioni:   1) configurare un alias dell'host remoto in modo da poterlo chiamare come se fosse localhost   2) Creare un componente server-side che faccia da proxy   3) Imbrogliare : l'unica risorsa che possiamo richiedere esternamente è Javascript...uhm...interessante
    48. 48. Ok, imbrogliamo! L'output dei servizi REST+JSON di Flickr (ma anche Google e altri) può avvenire in due modi:   <ul><ul><li>jsonFlickrApi({&quot;photos&quot;:{&quot;page&quot;:1, &quot;pages&quot;:5, &quot;perpage&quot;:100, &quot;total&quot;:500, &quot;photo&quot;:[{&quot;id&quot;:&quot;3123...)
    49. 49.   myCallbackFunction ({&quot;photos&quot;: {&quot;page&quot;:1, &quot;pages&quot;:5, &quot;perpage&quot;:100, &quot;total&quot;:500, ...) </li></ul></ul>  myCallbackFunction sarà il nome di una funzione Javascript a cui sarà passato l'oggetto JSON ritornato da Flickr   L'url è diventato: String url =  &quot; http://.../rest/?format=json& method =...& api_key =a...1& user_id =1234567@N01& jsoncallback = myCallbackFunction &quot;;
    50. 50. Un problema ed una soluzione: JSNI Problema <ul><ul><li>il nome del metodo di callback deve essere predefinito  
    51. 51. GWT rinomina i metodi per ridurre le dimensioni del js </li></ul></ul>Soluzione   Con JSNI definiamo codice Javascript in una una classe public native static void getJson(String callback , String url, MyHandler h ) /*-{ var script = document.createElement(&quot;script&quot;);  script.setAttribute(&quot;src&quot;, url+ callback ); script.setAttribute(&quot;type&quot;, &quot;text/javascript&quot;); window[callback] = function(jsonObj){ h .@ it.pronetics.MyHandler::handle (Lcom/google/gwt/core/client/JavaScriptObject;)( obj );     window[callback + &quot;done&quot;] = true; }        document.body.appendChild(script); }-*/;
    52. 52. Ancora J ava S cript N ative I nterface package it.pronetics; ...   public class MyHandler {      public void handle(JavaScriptObject javaScriptObject) {         //creiamo l'oggetto JSON         JSONObject object = new JSONObject(javaScriptObject);         // isObject() e isArray() ritornano null in caso di errore,         // il valore recuperato in caso di successo         JSONArray photos = object.get( &quot;photos&quot; ).isObject().get( &quot;photo&quot; ).isArray();         String thumbnail = buildPhotoUrl(photoJson, &quot;s&quot;);         ....         Image image = new Image(thumbnail);         gallery.setWidget(row, column, image);      } ... bla bla bla ... }
    53. 53. Finalmente...
    54. 54. Il mio widget public class ImageSlide extends Composite { //estendere la classe Composite come consigliato da GWT public ImageSlide(String thumbnail, String preview, final String link) {          VerticalPanel mainPanel = new VerticalPanel();         HorizontalPanel details = new HorizontalPanel();                  Image thumbnailImage = new Image(thumbnail);         mainPanel.add(thumbnailImage);         mainPanel.add(details);         mainPanel.setBorderWidth(1);                  Button show = new Button(&quot;Show&quot;);         Button open = new Button(&quot;Open&quot;);         details.add(show);         details.add(open);                  final PopupPanel popup = new PopupPanel();            Image previewImage = new Image(preview);         VerticalPanel imagePanel = new VerticalPanel();         imagePanel.add(previewImage);                  previewImage.addClickListener(new ClickListener(){ public void onClick(Widget sender) { popup.hide(); }  });         popup.setWidget(imagePanel);                  show.addClickListener(new ClickListener(){ public void onClick(Widget sender) { popup.show(); } });                  open.addClickListener(new ClickListener(){ public void onClick(Widget sender) { Window.open(link, &quot;_blank&quot;,&quot;enabled&quot;);}});                  initWidget(mainPanel); //chiamata obbligatoria!     } }
    55. 55. Già stiamo migliorando...
    56. 56. ...ma questa è meglio...
    57. 57. ...c'è anche qualche info...
    58. 58. ...ma come abbiamo fatto?     public ImageSlide(String thumbnail, String preview, String title, final String link) {        ... creo vari panel ...                  Image thumbnailImage = new Image(thumbnail);         thumbnailImage.setStyleName(&quot;image-panel&quot;);         mainPanel.add(thumbnailImage);         mainPanel.setCellHorizontalAlignment(thumbnailImage, HasHorizontalAlignment.ALIGN_CENTER);         mainPanel.add(details);                  Button open = new Button(&quot;View on Flickr&quot;, new OpenLinkOnClick(link));         open.setWidth(&quot;100%&quot;);         Button close = new Button(&quot;Close me!&quot;, new ClosePopupPanelOnClick(popup));         close.setWidth(&quot;100%&quot;);                  Image previewImage = new Image(preview);         VerticalPanel imagePanel = new VerticalPanel();         imagePanel.add(previewImage);                  infoPanel.add(new Label(title, true));         infoPanel.add(open);         infoPanel.add(close);                  previewTab.add(imagePanel, &quot;Image&quot;);         previewTab.add(infoPanel, &quot;Get Info&quot;);         previewTab.selectTab(0);         previewTab.setAnimationEnabled(true);                  previewImage.addClickListener(new ClosePopupPanelOnClick(popup));             thumbnailImage.addClickListener(new DisplayPopupOnClick(popup));                  initWidget(mainPanel); //chiamata obbligatoria!     }
    59. 59. Ma soprattutto CSS E' stato modificato il file FlickrGWT.css   .image-panel {     background: url('img/bg.png') no-repeat top center;     padding: 0px 10px 10px 10px; } Ricordate : GWT in fondo crea semplici pagine HTML i cui stili possono essere impostati con semplici CSS
    60. 60. La versione finale! <ul><ul><li>Modifichiamo il file FlickrGWT.html creando un layout HTML
    61. 61. Specifichiamo l'id del div che conterrà la nostra applicazione: RootPanel.get(&quot;flickr-gallery&quot;).add(gallery);
    62. 62. Scriviamo un po' di css e html e... </li></ul></ul>
    63. 63. Image Bundle? Problema Troppe request uccidono i nostri server Soluzione Una sola request per le immagini usate nel nostro applicativo
    64. 64. Image Bundle con GWT <ul><ul><li>L'unione di tutte le immagini in una sola è automatica
    65. 65. Basta definire una interfaccia interface ToolBarImage extends ImageBundle {          @Resource ( &quot;img/open.png&quot; )         AbstractImagePrototype open();         ....         @Resource ( &quot;img/save.png&quot; )         AbstractImagePrototype save();  }
    66. 66. L'utilizzo è ancora più semplice ToolBarImage bundle = (ToolBarImage)GWT.create(ToolBarImage. class ); Image save = bundle.save().createImage(); toolbar.add(save); </li></ul></ul>
    67. 67. Plugin e widget per la view
    68. 68. Alcune librerie utili <ul><ul><li>Spring Security + GWT http://www.insideit.fr/post/2009/02/19/How-to-:-Spring-Security-ex-Acegi-and-GWT
    69. 69. Dependency injection </li></ul></ul><ul><ul><ul><li>GIN - http://code.google.com/p/google-gin/
    70. 70. SUCO - http://code.google.com/p/suco/
    71. 71. RocketGWT - http://code.google.com/p/rocket-gwt/
    72. 72. SpringME - http://springframework.me </li></ul></ul></ul><ul><ul><li>Altri Framework </li></ul></ul><ul><ul><ul><li>GWT Toolbox - http://code.google.com/p/gwt-toolbox/
    73. 73. GWT Widget Library -http://gwt-widget.sourceforge.net/
    74. 74. GWITTIR - http://code.google.com/p/gwittir/ </li></ul></ul></ul><ul><ul><li>Hibernate + GWT </li></ul></ul><ul><ul><ul><li>Gilead - http://noon.gilead.free.fr/gilead/ </li></ul></ul></ul><ul><ul><li>Sviluppo Server Side </li></ul></ul><ul><ul><ul><li>Enunciate - http://enunciate.codehaus.org/ </li></ul></ul></ul>
    75. 75. Usciamo dal browser con PRISM Mozilla Prism è un plugin per Firefox che permette la trasformazione di applicazioni web in applicazioni desktop
    76. 76. Usciamo dalla rete con Google Gears <ul><ul><li>Database SQL
    77. 77. Geo localizzazione
    78. 78. Interazione col desktop
    79. 79. Local server per file, immagini, javascript, css </li></ul></ul>
    80. 80. Una combinazione vincente GWT + GEAR + PRISM = COOL APPLICATION
    81. 81. <ul><ul><li>http://code.google.com/webtoolkit/
    82. 82. http://www.ociweb.com/mark/programming/GWT.html
    83. 83. http://code.google.com/p/gwt-google-apis/
    84. 84. http://gears.google.com/
    85. 85. http://www.gwtsite.com/
    86. 86. http://www.ongwt.com 
    87. 87. http://labs.mozilla.com/projects/prism/ </li></ul></ul>Link & Libri
    88. 88. <ul><ul><li>Davide Cerbo [email_address] http://davide.cerbo.born-to-co.de
    89. 89. Stefano Linguerri stefano.linguerri @pronetics.it http://www.eljeko.net </li></ul></ul>Contatti
    90. 90. Q&A  

    ×