Este documento discute temas avanzados de GWT como pruebas de cliente, depuración, JSNI, enlace diferido, AJAX y RPC. Explica cómo ejecutar pruebas de cliente en diferentes modos como JUnit, Selenium y RemoteWeb. También cubre cómo depurar aplicaciones GWT de forma similar a otras aplicaciones Java y la recomendación de hacer TDD en lugar de depurar. Luego describe características clave de GWT como JSNI para usar JavaScript dentro de Java, enlace diferido para seleccionar implementaciones basadas en el navegador y AJ
3. Ejecutar tests (de Cliente JS)
Dos modos de ejecución:
– Desarrollo
• Se compila la aplicación para HtmlUnit
• Se ejecuta HtmlUnit y Jetty
• Run As → GWT Junit Test
– Producción
• Se compila la aplicación para el browser por defecto
• Se ejecuta automáticamente el navegador y Jetty
• Run As → GWT Junit Test (Production Mode)
4. Otros modos de Test de cliente
El resto de modos de Test requieren realizar algunas operaciones en eclipse:
Lanzar el test en modo junit
– Run As → Junit Test
El test fallará porque le falta añadir al classpath los directorios de fuentes
– Run → Run Configurations → HelloTest → ClassPath → User Entries → Advanced →
Add Folders → (src y test)
Probar el test que debe pasar
Añadir las opciones que deseemos:
– Run → Run Configurations → HelloTest → xArgument → VMArguments
Nota: poner las siguientes opciones entre comillas dobles
– Manual
-Dgwt.args=-runStyle Manual:1
– Selenium
-Dgwt.args=-runStyle Selenium:myhost:4444/*firefox
– BrowserManagerServer
-Dgwt.args=-runStyle RemoteWeb:rmi://myhost/ie8
java -cp gwt-user.jar;gwt-dev.jar
com.google.gwt.junit.remote.BrowserManagerServer
ie8 "C:Program FilesInternet ExplorerIEXPLORE.EXE"
5. Depurar
• La depuración de aplicaciones GWT (cliente) es exactamente igual que para
cualquier otra aplicación java:
– Poner puntos de control
– Debug As → (Web Application | GWT Junit Test | GWT Junit Test
(Production Mode)
– Conectar el browser
– Utilizar la vista de depuración
• Se puede mezclar depuración del lado cliente con lado servidor.
• Al igual que depurando aplicaciones gráficas, la depuración continúa cuando
ocurre un evento.
• Recomendación: NO depurar → hacer TDD
7. JSNI (JavaScript Native Interface)
• Código Javascript en comentarios java
• Permite utilizar Js dentro de GWT y al revés.
• Usa la declaración 'native' que indica a java que
ese método se resolverá en tiempo de
'runtime'
• Los métodos nativos se puede utilizar en los
IDEs sin que marquen el código con error.
• El compilador GWT lo detecta y lo copia en el
fichero javascript resultante
• Finalmente se comprime y obfusca junto con el
resto de código
8. JSNI
## En este ejemplo exportamos un método creado en GWT y lo dejamos disponible en el objeto Window
public class HelloClass implements EntryPoint{
String prefix = "Hello: ";
// Al cargar la aplicacion, exportamos el metodo
public void onModuleLoad() {
exportHelloMethod(this);
}
// Metodo que queremos usar desde javascript
public String helloMethod(String name) {
return prefix + " " + name;
}
// JSNI: ponemos nuestro método en el objeto window
private native void exportHelloMethod(HelloClass instance) /*-{
$wnd.hello = function(name) {
return instance.@jschismes.client.HelloClass::helloMethod(Ljava/lang/String;) (name);
};
}-*/;
}
9. Deferred Binding
• Son clases java que no se utilizan hasta el
momento de compilación
• Se seleccionan diferentes implementaciones
para cada navegador, lenguage …
• Hace posible el emulador JRE de GWT
• Elimina el código innecesario para cada
plataforma.
• Es el principal responsable del rendimiento del
código JS generado por GWT
10. Deferred Binding
# El modo de establecer la opacidad es diferente en IE y en otros navegadores
class DOM {
private static CSSImpl cssImpl = GWT.create(CSSImpl.class);
public void cssClearOpacity(Element e) {
cssImpl.cssClearOpacity(e.getStyle();
}
public native void cssSetOpacity(Element e, double value) {
cssImpl.cssSetOpacity(e.getStyle(), value;
}
}
class CSSImpl { <replace-with class="[...].CSSImplIE">
public void cssClearOpacity(Style style) { <when-type-is class="[...].CSSImpl"/>
style.setProperty("opacity", ""); <any>
} <when-property-is name="user.agent" value="ie6"/>
public native void cssSetOpacity(Style style, double value) { <when-property-is name="user.agent" value="ie8"/>
style.setProperty("opacity", String.ValueOf(value); </any>
} </replace-with>
}
class CSSImplIE extends CSSImpl{
@Override
public native void cssClearOpacity(Style style) /*-{
style.filter = '';
}-*/;
@Override
public native void cssSetOpacity(Style style, double value) /*-{
style.filter = 'alpha(opacity=' + (value * 100) + ')';
}-*/;
}
11. AJAX, RPC
• GWT puede hacer llamadas Ajax de 4 tipos
– XML
– JSON
– TEXT o HTML
– RPC
• RPC es un contrato entre servidor (java) y cliente.
• Se pasan objetos (pojo) que se puedan serializar.
– No todos los objetos serializables en JRE son serializables
– Tienen que ser compatibles con la emulación JRE de GWT.
• En el servidor hay que extender RemoteServiceServlet
• Realmente se transfieren objetos jSON especiales que ambos
extremos saben convertir en su propia representación de objeto
12. // Interfaces necesarios (Se ponen en la parte cliente)
@RemoteServiceRelativePath ("greet")
public interface GreetingService extends RemoteService {
RPC String greetServer(String name) throws IllegalArgumentException;
}
public interface GreetingServiceAsync {
void greetServer(String input, AsyncCallback<String> callback)
throws IllegalArgumentException;
}
// Codigo cliente
public class Hello implements EntryPoint {
private final GreetingServiceAsync greetingService =
GWT.create(GreetingService.class);
greetingService .greetServer(textToServer, new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(String result) {
}
});
}
// Codigo en el servidor
public class GreetingServiceImpl extends RemoteServiceServlet
implements GreetingService {
public String greetServer(String input) throws IllegalArgumentException {
}
}
<web-app>
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>ws.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/hello/greet</url-pattern>
</servlet-mapping>
</web-app>
13. Inportar proyecto maven en eclipse
Importar el proyecto maven:
– File → Import → Maven projects.
Añadir al proyecto el SDK de GWT
Especificar la ubicación del directorio web:
– Properties → Web Application → This project has a WAR →
directory → src/main/webapp → Mark Launch from this
Borrar index.html
Crear index.html con el plugin GWT
– New → (G) HTML page → index.html → ws.Application
15. SEO
- GWT produce javascript con capacidades muy avanzadas de manejar el DOM
y de ejecutar Ajax.
- Podemos modificar el comportamiento de una página utilizando javascript
(progressive enhancement).
- Podemos reaprovechar el código de una funcionaliad añadida en una parte de
nuestra aplicación en cualquier otra.
- Gquery, es un clon de jquery para Gwt.
- La versión 0.2-patched es funcional y estable (1.6.x).
http://gwt-workshop.googlecode.com/svn/trunk/lib/gwtquery-0.2-patched.jar
- La versión 0.1-SNAPSHOT-patched es funcional (2.0.x), pero la parte de
efectos es inestable, aunque los selectores y eventos funcionan bien.
http://gwt-workshop.googlecode.com/svn/trunk/lib/gwtquery-1.0-patched-SNAPSHOT.jar
- Parte del código de Gquery estará en el core de GWT (selectores Css)
17. Creando librerías Js con GWT
- Los objetos, métodos y variables creados con GWT se pasan a JS,
pero el compilador obfusca estos nombres aleatoriamente de
manera que es imposible referenciarlos desde javascript.
- GwtExporter permite exportar las clases y métodos que queramos
con nombres conocidos en tiempo de compilación
- Leer el tutorial:
http://code.google.com/p/gwtchismes/wiki/Tutorial_ExportingGwtLib
rariesToJavascript_es
18. Preguntas
Manuel Carrasco Moñino
http://manolocarrasco.blogspot.com
twitter.com/dodotis
manolo@apache.org