3. Estructura del proyecto
src/.../client: código para el
navegador
src/.../public: html, css, img ...
src/.../server: código para el
servidor
[project].gwt.xml: configuración
test/.../client: tests de cliente
test/.../server: tests java
war/ cosas de despliegue
– war/lib
– war/WEB-INF
4. Pasos para crear un proyecto
1. Crea un nuevo proyecto
2. Configura el módulo
3. Crea tu página html y pon la llamada JS
4. Desarrolla en java: cliente, servidor, RPC
5. No olvides Testear: GWTTestCase
6. Prueba y depura: DevMode + Browser + Plugin
7. Compila a JS
8. Despliega
9. Olvidaté de versionado, optimización,
obfuscación, caché, refactoring, reusing ...
5. Crear el proyecto
$ ~/gwt-current/webAppCreator -help
Google Web Toolkit 2.0.3
WebAppCreator [-overwrite] [-ignore] [-out dir] [-junit pathToJUnitJar] moduleName
where
-overwrite Overwrite any existing files
-ignore Ignore any existing files; do not overwrite
-out The directory to write output files into (defaults to current)
-junit Specifies the path to your junit.jar (optional)
and
moduleName The name of the module to create (e.g. com.example.myapp.MyApp)
$ ~/gwt-current/webAppCreator
-junit mylibs/junit-4.3.jar
-overwrite
-out Hello
com.foo.Hello
Created directory Hello/src
Created directory Hello/war
Created directory Hello/war/WEB-INF
[…]
6. Configurar el módulo
<module rename-to=”hola” >
<!-- Librerias en el cliente -->
<inherits name='com.google.gwt.user.User'/>
<inherits name="com.google.code.p.gwtchismes.GWTChismes" />
<!-- Clase(s) a cargar en la inicialización -->
<entry-point class='com.foo.Hello'/>
<!-- Hojas de estilo -->
<stylesheet src="JsUpload.css"/>
<!-- Propiedades específicas de módulos importados -->
<set-property name="export" value="yes" />
<!-- Lenguajes -->
<!-- <extend-property name="locale" values="es" /> -->
<!-- Linker std, xs, … -->
<!-- <add-linker name="xs"/> →
<!-- Deferred binding, … -->
<replace-with class="com.foo.MyClassIE">
<when-type-is class="com.foo.MyClass"/>
<any>
<when-property-is name="user.agent" value="ie6"/>
<when-property-is name="user.agent" value="ie8"/>
</any>
</replace-with>
</module>
7. Página html de la aplicación
<!-- Hacer la llamada al fichero de javascript generado para nuestra aplicación
en cualquier fichero estático o dinámico. -->
<html>
<head>
</head>
<body>
<!-- Llamada a nuestra aplicación -->
<script id="ID" type="text/javascript" language="javascript"
src="com.foo.Hello.js?123&provider=1">
</script>
<!-- Necesario si queremos tener historia -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
style="position:absolute;width:0;height:0;border:0"></iframe>
<!-- Se puede poner todo el contenido html que queramos y manipularlo -->
<h1>Hello</h1>
<!-- GWT no es intrusivo, se puede utilizar cualquier otra librería/s js -->
<script id="ID" type="text/javascript" language="javascript"
src="jquery.js">
</script>
</body>
</html>
8. Trabajar en Java
- El método EntryPoint se llama cuando la aplicación se carga en el navegador
- GWT.create permite asociación aplazada de clases 'deferred binding'
- La clase DOM sirve para manejar elementos de navegador
package com.foo.client;
import [...]
public class Hello implements EntryPoint {
// This method is called whenever the browser loads the page
public void onModuleLoad() {
MyClass impl = GWT.create(MyClass.class);
DOM.getElementById("id").getStyle().setProperty("display", "none");
}
}
9. ¿Qué obtenemos al Compilar?
## Único Fichero a incluir en el HTML
## Se encarga de detectar browser/lang y cargar el fichero de aplicacion adecuado
## No se debe cachear
com.foo.Hello.nocache.js
## Cada fichero para la combinación browser/language
## Se pueden generar ficheros '.js' o '.html' dependiendo del linker
## cross-site (xs), standard (std)
## Se puede cachear
1102DEF681997CEB9DDF55DEA52DAC77.cache.js (ó .html)
35041D1CDE8A3F7BA84E28F014AD7763.cache.js
855ACC0BD175268F9BFBDDD1AC46D60C.cache.js
BCAE487AACB322FA340C97DFE205CF9C.cache.js
EAB3A6766FC64B8FB876749E68EF311D.cache.js
## Definición de llamadas rpc
DACD019E1AB65BD2BCAC2F7BD9DB85F2.gwt.rpc
## Ficheros estáticos
clear.cache.gif
Hello.css
history.html
Hello.css
Hello.html
images/
10. ¿Cómo es el JS generado?
### Compilando con el parámetro -style PRETTY
function getStylePrimaryName(elem){
var fullClassName, spaceIdx;
fullClassName = elem['className'] == null?null:String(elem['className']);
spaceIdx = fullClassName.indexOf(fromCodePoint(32));
if (spaceIdx >= 0) {
return fullClassName.substr(0, spaceIdx - 0);
}
return fullClassName;
}
function removeStyleName_0(style){
setStyleName_0(this.getStyleElement(), style, false);
}
### Por defecto -style OBFUSCATED
_=gB.prototype=new zdb();_.gC=lB;_.tI=22;function tB(f,d){var a,b,c,e,g;for(b=0;b<d.length;+
+b){c=fi+(d[b]!=null?d[b]:fi);a=sx+b+ux;for(;;)
{e=f.indexOf(a);if(e<0)break;g=fi;if(e+a.length<f.length)g=gMb(f,e+a.length);f=f.substr(0,e-
0)+c+g}}return f}
function mC(c,a,d){var b;b=d>0?~~(a*100/d):0;nC(c,b,a,d)}
11. Usar la caché de cliente
### Configuración Apache para GWT
ExpiresActive on
ExpiresDefault "now plus 2 hours"
# Dont cache the main file (browser and locale detector, and application file selector)
# ie: com.miraiespana.home.gwt.Home.nocache.js
<Files ~ *.nocache.*>
ExpiresDefault "now plus 2 minutes"
Header set Cache-Control "no-store,must-revalidate"
AddOutputFilter DEFLATE
</Files>
# Cache the application files
# ie: 1102DEF681997CEB9DDF55DEA52DAC77.cache.js
<Files ~ *.cache.*>
ExpiresDefault "now plus 2 years"
Header set Cache-Control "max-age=290304000,public"
</Files>
13. Plugin de google para eclipse
El plugin incluye:
– Asistente para creación de proyectos.
– Servidor y Lanzador de aplicaciones
– Lanzador de Tests
– SDK para GWT
– SDK para GAE
Web oficial:
– http:http://code.google.com/eclipse/
14. Plugin para Navegadores
Para depurar y trabajar en modo desarrollo es necesario añadir a nuestro
navegador el plugin para GWT
Existen plugins para:
– FF
– Chrome
– IE
¿Cómo funciona?
– GWT compila la aplicación a javascript añadiendo cierta información de
control.
– Se utiliza un canal de comunicación entre el plugin del browser y el
modo de desarrollo de GWT (integrado en eclipse)
– Eclipse interacciona con el usuario mostrando las líneas de código y con
el navegador y respetando los puntos de control
15. Importar un proyecto a Eclipse
File → Import → Existing projects into workspace → Browse
18. Ejecutar en modo desarrollo
Borrar ficheros *.launch (ya no son necesarios con el plugin)
Run As → Web Application
Abrir la URL indicada en el Navegador (si no tiene el plugin preguntará).
20. Ant
Los proyectos GWT para 'ant' se crean con la herramienta
webAppCreator
Se genera un fichero build.xml con las tareas de:
– Ejecutar Tests
• test.dev (HtmlUnit)
• test.prod (Browser)
– Ejecutar en Modo desarrollo
• devmode
– Compilar las clases java
• javac
• javac.tests
– Compilar el código java a javascript
• gwtc
– Producir el fichero de la aplicación empaquetado
• war
21. Maven
Aunque hay varios plugins para maven, se debe usar el alojado en codehaus
http://mojo.codehaus.org/gwt-maven-plugin/.
Se necesita maven 2.2.x para que funcione.
Existe un arquetipo para crear un proyecto GWT:
– mvn archetype:generate -DarchetypeGroupId=org.codehaus.mojo
-DarchetypeArtifactId=gwt-maven-plugin -DarchetypeVersion=1.1
-DgroupId=ws -DartifactId=GwtWsHelloWorld
– Después editar el fichero pom.xml y hacer estas modificaciones
<gwt.version>2.0.3</gwt.version>
[...]
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<configuration>
<runTarget>myGroupId.Application/Application.html</runTarget>
</configuration>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
22. Maven
Goles:
– 'mvn gwt:run' ejecutar el modo desarrollo
– 'mvn gwt:compile' compilar a javascript
El resto de goles Gwt no funcionan o no son necesarios
A partir de ahora podemos utilizar maven como en cualquier otro
proyecto java:
– 'mvn clean test package emma:emma site' …
Nota: la instrumentalización de cobertura para tests GWT sólo
funciona con Emma.
Importar el proyecto en eclipse como un proyecto maven con el
plugin m2eclipse de sonatype
24. Estructura de las librerías GWT
• Crear un módulo (normalmente sin entryPoint)
• Crear código Java
• Añadir elementos estáticos
• Generar un fichero jar que incluya:
– Código Fuente *.java
– Elementos Públicos (css, jpg ...)
– Fichero de Módulo *.gwt.xml
– Clases compiladas *.class
– META-INF/MANIFEST.MF
• Conclusión: igual que en java
– Se puede utilizar maven
– Se puede utilizar ant
25. Cómo se usan la Librerías GWT
• Añadir el fichero .jar al classpath
• Heredar el módulo de la librería en nuestro módulo.
Incluir librerías que no se utilizan sólo penaliza el tiempo de compilación,
porque todo el código no usado será descartado de nuestro javascript
final.
## Hello.gwt.xml
<module rename-to=”hola” >
[…]
<!-- Módulo/s que la librería provee -->
<inherits name="com.google.code.p.gwtchismes.GWTChismes" />
<!-- Otras cosas necesarias para usar la librería -->
<stylesheet src="GWTC-compressed.css"/>
[…]
</module>
26. Preguntas
Manuel Carrasco Moñino
http://manolocarrasco.blogspot.com
twitter.com/dodotis
manolo@apache.org