GWT

2,526 views
2,134 views

Published on

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

  • Be the first to like this

No Downloads
Views
Total views
2,526
On SlideShare
0
From Embeds
0
Number of Embeds
57
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

GWT

  1. 1. GWTGoogle Web Toolkit
  2. 2. Que es GWT• Es un Framework de desarrollo propiedad de Google, con el cual se le dan vida a aplicaciones reales y complejas como Google Maps, Google AdWords, Orkut• Es completamente gratis y de código abierto
  3. 3. Que requiere GWT• De manera general solo se necesita el SDK de GWT, pero pueden usarse diferente plugins liberados por Google para facilitar el desarrollo como: – Google Eclipse Plugin – Window Builder Pro – GWT Designer(parte de Window Builder Pro) – SpeedTracer
  4. 4. Instalación de los plugins• Los plugins pueden instalarse desde el software manager de Eclipse.• Help->Install new software.• Debemos agregar los repositorios necesarios para instalar los plugins, los cuales están disponibles en la siguiente url: http://code.google.com/intl/es/webtoolkit/do wnload.html
  5. 5. Ventajas• Modelo de programación similar a aplicaciones de escritorio Swing.• Fácil uso de código del servidor sin importar como se codifica este.• Es compatible con varios browsers.• Evita refrescar el browser cada vez que se realiza una petición.
  6. 6. Desventajas• La estructura del proyecto cambia drásticamente.• Los JSP, JSF desaparecen.• El modelo de programación es diferente a los habituales proyectos web Java.• Hace uso intensivo de JavaScript, lo cual puede incompatibilizarlos con browsers antiguos o dispositivos de poca capacidad.• Alto conocimiento de la herramienta para optimización
  7. 7. Estructura de un proyecto• HTML Host Pages• Distribución de paquetes y directorios• Modulos• Modulos Base
  8. 8. Distribución de paquetes y directorios• Un proyecto GWT tiene una distribución de directorios especifica para su código de cliente y de servidor:
  9. 9. Distribución de paquetes y directorios Cliente• En la paquete cliente, están todas las clases que representa la interface grafica.• El modelo es muy similar a las aplicaciones Swing, su manejo de eventos y componentes gráficos.• Permite la programación de la interfaces se realice con Java y un subconjunto bastante amplio de las clases base.• Contiene las interfaces Java para usar los servicios RPC
  10. 10. Distribución de paquetes y directorios Servidor (RPC)• El paquete de servidor contiene el código que se ejecutara desde el servidor.• Contiene los servicios que se ejecutaran de una manera fácil, síncrona o asíncronamente desde la interface grafica.• Puede hacer uso de otras clases y frameworks java para facilitar el uso de código del servidor.
  11. 11. HTML Host Pages• Son paginas que funcionan como punto de entrada a una aplicación GWT, son generadas por el compilador de GWT, pero se pueden modificar o llamar desde otras paginas.• Contienen la llamada a la clase EntryPoint, la cual es la clase que funciona como punto de entrada a la aplicación y es donde se crean los componentes visuales.
  12. 12. HTML Host Pages
  13. 13. Modulos• Un modulo es una aplicación o una parte de una aplicación GWT.• Pueden o no tener una clase que implemente la interface EntryPoint.• Si tienen la clase EntryPoint indica que tiene contenido ejecutable por el cliente, pero si no, se debe heredar desde otro modulo para utilizar su funcionalidad.
  14. 14. Archivo <NombreModulo>.gwt.xml• Contiene la definición del modulo y los módulos de los cuales depende.• Contiene la distribución de paquetes.
  15. 15. Archivo <NombreModulo>.gwt.xml<module> <inherits name="com.google.gwt.user.User"/> <inherits name="com.google.gwt.user.theme.standard.Standa rd"/> <inherits name="com.smartgwt.SmartGwt"/> <entry-point class="com.efibs.test.ui.GWTRoot.client.GWTRoot "/></module>
  16. 16. Uso de módulos• Codigo que no implementa una clase EntryPoint• Se debe heredad para usar su funcionalidad.• La herencia debe estar anotada en el archivo gwt.xml como una línea inherits <inherits name="com.smartgwt.SmartGwt"/>
  17. 17. EntryPoint Class• Esta clase contiene el metodo que inicializa un modulo.• Es similar al método main para Java o C.• Inicializa todo los controles requeridos.• Implementa la interface EntryPoint.
  18. 18. EntryPoint Classs1 package com.efibs.test.ui.BasicModule.client;23 import com.google.gwt.core.client.EntryPoint;4 import com.google.gwt.event.dom.client.ClickEvent;5 import com.google.gwt.event.dom.client.ClickHandler;6 import com.google.gwt.user.client.Window;7 import com.google.gwt.user.client.ui.Button;8 import com.google.gwt.user.client.ui.RootPanel;910 /**11 * Entry point classes define <code>onModuleLoad()</code>.12 */13 public class BasicModule implements EntryPoint {14 private Button clickMeButton;15 public void onModuleLoad() {16 RootPanel rootPanel = RootPanel.get();1718 clickMeButton = new Button();19 rootPanel.add(clickMeButton);20 clickMeButton.setText("Click me!");21 clickMeButton.addClickHandler(new ClickHandler(){22 public void onClick(ClickEvent event) {23 Window.alert("Hello, GWT World!");24 }25 });26 }27 }
  19. 19. Diseño visual de UI• El plugin gratuito Window Builder Pro, nos permite realizar un diseño visual de toda la interface grafica.• Para una clase GWT, realizan click derecho- >Abrir con
  20. 20. Diseño visual de UI
  21. 21. Widgets• GWT cuenta con una gran cantidad de controles gráficos o Widgets.• También existen librerías de terceros que proporcionan nuevos Widgets – SmartGWT http://code.google.com/p/smartgwt/ – ExtGWT http://www.sencha.com/products/extgwt/
  22. 22. Widgets Básicos
  23. 23. Eventos de los Widgets• Como las clases Swing, los widgets GWT responden a diferentes eventos, ya sea del teclado, del ratón o ambos.• Se pueden agregar tantos manejadores de eventos como sea necesario.• Se puede tener cualquier tipo de código en los manejadores de eventos, ya sea llamadas a código del servidor o interacción con otro widgets.
  24. 24. Eventos de los Widgets1 Button btnAceptar = new Button("New button");2 btnAceptar.addClickHandler(new ClickHandler() {3 public void onClick(ClickEvent event) {4 Window.alert("hola mundo");5 }6 });
  25. 25. RPC (Remote Procedure Call)• GWT ofrece una fácil integración con codigo del lado del servidor.• Se inicia como una interface la cual contiene la definición del servicio.• Existe otra interface la cual define el servicio de manera asíncrona.• Una clase Java que implementa la interface de servicio y codifica sus métodos.
  26. 26. La interface de servicio1@ RemoteServiceRelativePath("LoginService")2 public interface LoginService extends RemoteService {3 public String login(String usuario, String password);4 /**5 * Utility class for simplifying access to the instance of async service.6 */7 public static class Util {8 private static LoginServiceAsync instance;9 public static LoginServiceAsync getInstance(){10 if (instance == null) {11 instance = GWT.create(LoginService.class);12 }13 return instance;14 }15 }
  27. 27. La interface de servicio asincrona1 public interface LoginServiceAsync {2 public void login(String usuario, String password, AsyncCallback<String> callback);3 }
  28. 28. La implementación del servicio1 @SuppressWarnings("serial")2 public class LoginServiceImpl extends RemoteServiceServlet implements LoginService {34 @Override5 public String login(String usuario, String password) {6 if("admin".equals(usuario) && "admin".equals(password)){7 return "Usuario logueado";8 }9 else{10 return "Usuario o contraseña invalidas";11 }12 }13 }
  29. 29. Llamando al método RPC
  30. 30. Llamando al método RPC (Asíncrona)1 final LoginServiceAsync loginServiceAsync = GWT.create(LoginService.class);2 btnAceptar.addClickHandler(new ClickHandler() {3 public void onClick(ClickEvent event) {4 vwldrLoadingViewnbsp.setVisible(true);5 loginServiceAsync.login(txtUsuario.getText(), txtPassword.getText(), new AsyncCallback<String>() {6 @Override7 public void onSuccess(String result) {8 Window.alert("Respuesta del servidor: " + result);9 if(result.contains("log")){10 rootPanel.clear();11 rootPanel.add(new SearchPanel());12 }13 }14 @Override15 public void onFailure(Throwable caught) {16 Window.alert("error: " + caught.getMessage());17 }18 });19 vwldrLoadingViewnbsp.setVisible(false);20 }21 });
  31. 31. Llamando al método RPC (Síncrona)1 final LoginService loginService = GWT.create(LoginService.class);2 btnAceptar.addClickHandler(new ClickHandler() {3 public void onClick(ClickEvent event) {4 vwldrLoadingViewnbsp.setVisible(true);5 String result = loginService.login(txtUsuario.getText(), txtPassword.getText());6 Window.alert("Respuesta del servidor: " + result);7 if(result.contains("log")){8 rootPanel.clear();9 rootPanel.add(new SearchPanel());10 }11 vwldrLoadingViewnbsp.setVisible(false);12 }13 });
  32. 32. Ejecutar UI con muchas dependencias• Las interfaces de la aplicaciones complejas suelen volverse muy pesadas, estas hacen uso no solo de widgets de GWT sino de librerías de terceros, imágenes y JavaScript.• Esto se puede solucionar haciendo una ejecución en paralelo de la interface, la cual descargara la interface grafica sin bloquear la UI Actual.• GWT.runAsync Permite llamar código en segundo plano, normalmente sin ninguna demora aparente.
  33. 33. Ejecutar UI con muchas dependencias
  34. 34. Ejecutar UI con muchas dependencias1 GWT.runAsync(new RunAsyncCallback() {23 @Override4 public void onSuccess() {5 rootPanel.clear();6 rootPanel.add(new UIPesada());7 }89 @Override10 public void onFailure(Throwable reason) {11 Window.alert("Error con UI pesada");1213 }14 });
  35. 35. Seguridad GWT• GWT no tiene como seguir una sesión de usuario así que debe seguirse por medio de un servicio RCP.• GWT no realiza comprobaciones cuando se modifica el contenido HTML desde fuera del entorno GWT.• Se debe tener cuidado con el uso de cadenas obtenidas desde el cliente y el procesamiento de request Json o Xml.• Evitar el uso de JSNI
  36. 36. Modelo de Sesión GWT
  37. 37. Modelo de Sesión GWT1 public String login(String usuario, String password){2 if("admin".equals(usuario) && "admin".equals(password)){3 HttpSession session = this.getThreadLocalRequest().getSession(true);4 session.setAttribute(USER_LOGED_VAR, "usuario autenticado");5 return "Usuario logueado";6 }7 else{8 return "Usuario o contraseña invalidas";9 }10 }11 public Boolean checkSession() {12 HttpSession session = this.getThreadLocalRequest().getSession(false);13 Boolean respuesta= Boolean.FALSE;14 if(session != null && session.getAttribute(USER_LOGED_VAR) != null){15 respuesta = Boolean.TRUE;16 }17 return respuesta;18 }19 public void logoff() {20 HttpSession session = this.getThreadLocalRequest().getSession(false);21 if(session!=null){22 session.setAttribute(USER_LOGED_VAR, null);23 session.invalidate();24 }
  38. 38. Seguridad XSS• La seguridad respecto a los ataques XSS se validan mediante una programación rigurosa, reduciendo y evitando los vectores de ataque mas comunes como: – Evitando JavaScript en la HostPage que ejecuta la aplicación GWT – Evitando código que llame directamente el innerHTML de los widgets – Usar JSON API para parsear cadenas inseguras o de fuentes desconocidas – Usar JavaScript que use la función eval – Si se usa JSNI evitar código inseguro como usar innerHTML, eval o escribiendo directamente con document.write
  39. 39. Seguridad XSS• Se debe inspeccionar y escapar cualquier cadena que se use como innerHTML• Verificar y escapar cualquier cadena que se pase al parser JSON de GWT
  40. 40. Seguridad XSRF• Los ataques pueden ser el robo de la cookie de sesión y una manera para solucionar esto es haciendo uso del RequestBuilder para enviar el valor de la cookie de sesión, si este valor llega al servidor como un valor diferente al esperado, se trata de un ataque XSRF.
  41. 41. Seguridad XSRF (Servidor indicar sesión)1 public String login(String usuario, String password){2 if("admin".equals(usuario) && "admin".equals(password)){3 HttpSession session = this.getThreadLocalRequest().getSession(true);4 session.setAttribute(USER_LOGED_VAR, "usuario autenticado");5 String sessionId= createUID();6 session.setAttribute(USER_SESSION_ID, sessionId);7 this.getThreadLocalResponse().addCookie(new Cookie(USER_SESSION_ID, sessionId));8 return "Usuario logueado";9 }10 else{11 return "Usuario o contraseña invalidas";12 }13 }
  42. 42. Seguridad XSRF (Request Por RequesBuilder)1 RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, url);2 rb.setHeader("uuid", Cookies.getCookie("uuid"));3 rb.sendRequest(null, myCallback);
  43. 43. Seguridad XSRF (Servidor verificar cookie)1 private Boolean verificarCookie(HttpServletRequest request, HttpServletResponse response){2 Boolean respuesta = Boolean.FALSE;3 String headerValue = request.getHeader(USER_SESSION_ID);4 String value = (String) request.getSession(false).getAttribute(USE R_SESSION_ID);5 if(value.equals(headerValue)){6 respuesta = Boolean.TRUE;7 }8 return respuesta;9 }
  44. 44. Seguridad XSRF Para Servicios RCP (Servidor)• Se debe agregar referebcua a el servlet XsrfTokenServiceServlet<servlet> <servlet-name>xsrf</servlet-name> <servlet-class> com.google.gwt.user.server.rpc.XsrfTokenService Servlet </servlet-class></servlet><servlet-mapping> <servlet-name>xsrf</servlet-name> <url-pattern>/gwt/xsrf</url-pattern></servlet-mapping>
  45. 45. Seguridad XSRF Para Servicios RCP (Servidor)• Se debe agregar un parámetro de contexto el cual identifiqué la cookie con la cual se debe realizar la verificación.<context-param> <param-name>gwt.xsrf.session_cookie_name</param- name> <param-value>JSESSIONID</param-value></context-param>
  46. 46. Seguridad XSRF Para Servicios RCP (Servidor)• Los servicios RCP que deba implementar proteccion XSRF, deben heredar de la clase XsrfProtectedServiceServlet.public class MyServiceImpl extends XsrfProtectedServiceServlet implements
  47. 47. Seguridad XSRF Para Servicios RCP (Cliente)• Las interfaces que definen los servicios deben heredar de la interface XsrfProtectedService.• O las Interfaces deben ser anotadas con @XsrfProtect.• Las llamadas deben de obtener un tocken antes de cada petición del Servlet XsrfTokenService y luego adjuntar en su llamada el token obtenido.
  48. 48. Seguridad XSRF Para Servicios RCP (Cliente)1 XsrfTokenServiceAsync xsrf = (XsrfTokenServiceAsync)GWT.create(XsrfTokenService.class);2 ((ServiceDefTarget)xsrf).setServiceEntryPoint(GWT.getModuleBaseURL() + "xsrf");3 xsrf.getNewXsrfToken(new AsyncCallback<XsrfToken>() {45 public void onSuccess(XsrfToken token) {6 MyServiceAsync rpc = (MyServiceAsync)GWT.create(MyService.class);7 ((HasRpcToken) rpc).setRpcToken(token);89 // make XSRF protected RPC call10 rpc.doStuff(new AsyncCallback<Void>() {11 // ...12 });13 }1415 public void onFailure(Throwable caught) {16 try {17 throw caught;18 } catch (RpcTokenException e) {19 // Can be thrown for several reasons:20 // - duplicate session cookie, which may be a sign of a cookie21 // overwrite attack22 // - XSRF token cannot be generated because session cookie isnt23 // present24 } catch (Throwable e) {25 // unexpected26 }27 });
  49. 49. JSNI (JavaScript Native Interface)• Código JavaScript creado como un comentario de un método marcado como nativo.• Permite la llamada de código Java desde los métodos marcados como nativo.
  50. 50. JSNI (JavaScript Native Interface)1 // Expose the following method into JavaScript.2 private static String formatAsCurrency(double x) {3 return NumberFormat.getCurrencyFormat().format(x);4 }56 // Set up the JS-callable signature as a global JS function.7 private native void publish() /*-{8 $wnd.formatAsCurrency =9 @org.example.yourcode.format.client.DateFormatterLib::formatAsCurre ncy(D);10 }-*/;1112 // Auto-publish the method into JS when the GWT module loads.13 public void onModuleLoad() {14 publish();15 }
  51. 51. Usando una Función JNDI1 <html>2 <head>34 <-- Include the GWT module that publishes the JS API -->5 <script src="org.example.yourcode.FormatLib.nocache.js"></sc ript>67 <-- Write some JS that uses that GWT code -->8 <script>9 function doStuff() {10 alert(formatAsCurrency(1530281));11 }12 </script>13 </head>
  52. 52. Usando una función Java desde JNDI1 package org.example.foo;2 public class Flipper {34 public native void flipName(String name) /*-{5 var re = /(w+)s(w+)/;6 var s = name.replace(re, $2, $1);7 this.@org.example.foo.Flipper::onFlip(Ljava/lang/S tring;)(s);8 }-*/;910 private void onFlip(String flippedName) {11 // do something useful with the flipped name12 }
  53. 53. IoC en GWT, GIN• Gin es una librerías que nos permite utilizar IoC en el código GWT, para facilitar el uso de algunos servicios complejos y aumentar el desacoplamiento de los diferentes artefactos de software.• Eliminar el código boilaparte o repetitivo el cual hace crecer de manera innecesaria la complejidad del código.
  54. 54. GIN• El modulo debe heredar del modulo Inject<module> ... <inherits name="com.google.gwt.inject.Inject"/> ...</module>
  55. 55. GIN• Definir la el Ginjector, el cual será la clase que hará de contrato para implementar los tipos que se desea instanciar sin codificación directa.public interface SimpleInjector extends Ginjector { MainUi getMainUi(); LoginServiceAsync getLoginServiceAsync(); LoginService getLoginService(); }
  56. 56. GIN• Declarar el enlace entre varias clases y proveedorespublic class SimpleInjectorImpl extends AbstractGinModule { protected void configure() { bind(MainUi.class).in(Singleton.class); bind(LoginServiceAsync.class).toProvider(LoginServiceIPro viderAsync.class); bind(LoginService.class).toProvider(LoginServiceIProvide.cla ss); } }
  57. 57. GIN• Anotar la interface marcada como injector con @GinModules(ClaseImplInjector.class)@GinModules(SimpleInjectorImpl.class)public interface SimpleInjector extends Ginjector { MainUi getMainUi(); LoginServiceAsync getLoginServiceAsync(); LoginService getLoginService(); }
  58. 58. GIN• Finalmente para usar el injector que definimos debemos hacer uso del metodo GWT.create(injectorinterace.class)public class GWTModule implements EntryPoint { private final SimpleInjector injector = GWT.create(SimpleInjector .class); public void onModuleLoad() { MainUi mainPanel = injector.getMainPanel(); RootPanel.get().add(mainPanel); } }
  59. 59. GIN• También existe la inyección diferida, la cual se ejecuta en tiempo de ejecución.public interface MyConstants extends Constants { String myWords(); } public class MyWidget { @Inject public MyWidget(MyConstants myconstants) { // The injected constants object will be fully initialized - // GWT.create has been called on it and no further work is necessary. } }
  60. 60. GIN• Inyección diferida para servicios remoto RPCpublic interface MyRemoteService extends RemoteService { ... } public interface MyRemoteServiceAsync { ... } public class MyWidget { @Inject public MyWidget(MyRemoteServiceAsync service) { // The service will be created by calling GWT.create(MyRemoteService.class) // prior to injection. } }
  61. 61. GWT Logging• GWT soporta Logging a través de la API de Logging de java.• El modulo deberá heredar del modulo Logging<inherits name="com.google.gwt.logging.Logging"/> <set-property name="gwt.logging.logLevel“ value="SEVERE"/> # To change the default logLevel <set-property name="gwt.logging.enabled" value="FALSE"/> # To disable logging <set-property name="gwt.logging.consoleHandler" value="DISABLED"/> # To disable a default Handler
  62. 62. GWT Logging• Los loggers, implementan handlers, estos handler manejan donde se muestra la información sobre los eventos que se logean, existen varios loggers como: – SystemLogHandler – DevelopmentModeLogHandler – ConsoleLogHandler – PopupLogHandler – SimpleRemoteLogHandler
  63. 63. GWT Logging• El logging remoto, el cual debe usarse junto con un Servlet.gwt.xml1 < inherits name="com.google.gwt.logging.Logging" >2 < set-property name="gwt.logging.simpleRemoteHand ler" value="ENABLED" >3 < /set-property >4 < /inherits >web.xml1 < servlet >2 < servlet- class>com.google.gwt.logging.server.RemoteLoggingServiceIm pl </servlet-class >3 < servlet-name >logger < /servlet-name >4 < /servlet >5 < servlet-mapping >6 < servlet-name>logger </servlet-name >7 < url-pattern>/YOURPROJECT/remote_logging </url-pattern >8 < /servlet-mapping >
  64. 64. GQuery• Gquery es un port de Jquery para GWT, el cual permite realizar las tareas de manipulación DOM de una manera mas sencillas y seguras.• Es gratuito y se puede conseguir en: – http://code.google.com/p/gwtquery/
  65. 65. GQuery1 import static com.google.gwt.query.client.GQuery.*;2 import com.google.gwt.query.client.Function;34 public void onModuleLoad() {5 //Hide the text and set the width and append an h1 element6 $("#text").hide()7 .css("width", "400px")8 .prepend("<h1>GwtQuery Rocks !</h1>");910 //add a click handler on the button11 $("button").click(new Function(){12 public void f() {13 //display the text with effects and animate its background color14 $("#text").as(Effects)15 .clipDown()16 .animate("backgroundColor: yellow", 500)17 .delay(1000)18 .animate("backgroundColor: #fff", 1500);19 }20 });21 }

×