Integración Capa Web de pojo-miniportal (1) 1. Cambiar tipo de proyecto maven de "JAR" a "WAR 2. Añadir dependencias del API de Tapestry 3. Añadir configuración del plugin de Jetty al pom.xml 4. Añadir el fichero src/main/jetty/jetty-env.xml a la estructura de vuestro proyecto. En ese fichero se define el nombre del DataSource que Jetty pone accesible por JNDI. La configuración no hace falta tocarla si se utilizan profiles como en los ejemplos (se usan variables). 5. En el pom.xml del proyecto, en la parte de filtrado de recursos, modificar la ruta al fuente de jetty-env.xml (ahora no hacen falta los "../ por no tener submódulos) 6. Añadir a vuestro fichero de configuración de Spring en src/ main/resources la definición de un DataSource que acceda al del servidor de aplicaciones (ver cómo se hace en pojominiportal) 7. Copiar src/main/webapp a vuestro proyecto, actualizando en WEB-INF/web.xml la referencia al fichero de configuración de Spring y el paquete base de la capa Web de vuestro proyecto
Integración Capa Web de pojo-miniportal (2) 8. Copiar de src/main/java todo lo que cuelga de es.udc.pojo.miniportal.web a vuestro proyecto, excepto es.udc.pojo.miniportal.web.pages.user (se irán copiando más adelante) 1. Hay que adaptar la clase SessionDispatcher para que trabaje con el UserService de vuestro proyecto 9. Copiar de src/main/resources todo a vuestro proyecto, excepto los ficheros de configuración de Spring e Hibernate y lo que cuelga de es.udc.pojo.miniportal.web.pages.user 10. Cambiar Layout.tml para que no haya enlaces a páginas que no existen (de momento). E.g. haciendo que apunten todas a Index. 11. Arrancar Jetty (mvn jetty:run) y comprobar que es posible acceder a la página principal (http://localhost:9090/ <<proyecto>>) 12. Integrar el resto de páginas (una cada vez)
Integración Capa Web de pojo-miniportal (3) Además, hay que tener en cuenta Habilitación del patrón Patrón Open Session In View Basta proceder como se indica en los ficheros src/main/webapp/ WEB-INF/web.xml y src/main/resources/pojo-miniportalspring-config.xml de pojo-miniportal Bases de datos de pruebas y de ejecución de aplicaciones En pojo-examples se usan dos bases de datos: una para pruebas (test) y otra para la ejecución de aplicaciones De esta manera, la ejecución de una aplicación no afecta a las pruebas, y viceversa Para crear los datos que necesita la aplicación para poder funcionar (e.g. categorías y productos en una tienda de comercio electrónico) Crear un script SQL (e.g. src/sql/2-createdata.sql) que introduzca los datos necesarios mediante sentencias INSERT INTO Integrar el script en el pom.xml (plugin SQL-> configuración no ligada a una fase) de manera que se ejecute cuando se teclea mvn sql:execute 3
Integración Capa Web de pojo-miniportal (4) Además, hay que tener en cuenta (cont) Bases de datos de pruebas y de ejecución de aplicaciones (cont) <plugin> <groupid>org.codehaus.mojo</groupid> <artifactid>sql-maven-plugin</artifactid>... <configuration> <driver>${jdbcdriver.classname}</driver>... <orderfile>ascending</orderfile> <fileset> <basedir>${basedir}</basedir> <includes> <include>src/sql/1-createtables.sql</include> <include>src/sql/2-createdata.sql</include> </includes> </fileset> </configuration> 4
Integración Capa Web de pojo-miniportal (y 5) Además, hay que tener en cuenta (cont) Bases de datos de pruebas y de ejecución de aplicaciones (cont) <executions> <execution> <id>create-tables-for-testing</id> <phase>process-test-resources</phase> <goals> <goal>execute</goal> </goals> <configuration>... <fileset> <basedir>${basedir}</basedir> <includes> <include>src/sql/1-createtables.sql</include> </includes> </fileset> </configuration> </execution> </executions> </plugin> 5
Servicios XML (1) Se implementarán como páginas normales que generan XML en lugar de HTML Por defecto, el tipo de contenido que especifica Tapestry en las respuestas HTTP es text/html http://tapestry.apache.org/tapestry5/guide/content-type.html Los servicios XML deberían utilizar el tipo text/xml en las repuestas HTTP Es preciso usar la anotación @org.apache.tapestry5.annotations.contenttype sobre la clase página Ejemplo @ContentType("text/xml") public class XmlService { //... } 6
Servicios XML (2) Paso de parámetros El mecanismo habitual para pasar parámetros a una página es el uso del contexto de activación Ejemplo de invocación por GET http://.../xmlservice/1/hello Clase página @ContentType("text/xml") public class XmlService { //... void onactivate(int par1, String par2) { } //... //... } 7
Servicios XML (3) Paso de parámetros (cont) En el caso de parámetros de tipo String o Character, Tapestry necesita codificar algunos caracteres de forma especial, como por ejemplo el espacio en blanco, vocales con tilde, ñ s,etc., dado que en otro caso la URL no estaría en un formato legal Por ejemplo, si el segundo parámetro del ejemplo anterior fuese hello world, sería preciso emplear la URL http://.../xmlservice/1/hello$0020world La codificación que utiliza Tapestry, aunque legal, no sigue ningún estándar, por lo que no resulta conveniente usar el contexto de activación como mecanismo de paso de parámetros en un entorno de integración de aplicaciones con servicios XML 8
Servicios XML (4) Paso de parámetros (cont) Por ello, es más conveniente pasar los parámetros a la página como parámetros HTTP Ejemplo de invocación por GET http://.../xmlservice?par1=1&par2=hello Clase página @ContentType("text/xml") public class XmlService { //... @Inject private org.apache.tapestry5.services.request request; 9
Servicios XML (5) Paso de parámetros (cont) Clase página (cont) void onactivate() { String par1asstring = request.getparameter("par1"); String par2asstring = request.getparameter("par2"); //.. } Request.getParameter Devuelve el valor de un parámetro HTTP univaluado Si el parámetro no existe, devuelve null No realiza ningún tipo de conversión automáticamente: los valores se devuelven como String Request.getParameters Idem para parámetros multi-valuados 10
Servicios XML (6) Paso de parámetros (cont) Al realizar la invocación, los valores de los parámetros tienen que estar codificados según el formato MIME application/ x-www-form-urlencoded Ciertos caracteres (espacio en blanco, vocales con tilde, ñ s,etc.) se codifican de forma especial No es una restricción de Tapestry, sino la manera estándar de trabajar en HTTP con los valores de los parámetros Esto afecta a los parámetros de tipo String o Character Por ejemplo, si el segundo parámetro del ejemplo anterior fuese hello world, sería preciso usar el valor hello+world http://.../xmlservice?par1=1&par2=hello+world Si el cliente es Java, puede usar java.net.urlenconder para realizar la codificación encodedvalue = URLEnconder.encode(value, "UTF-8"); 11
Servicios XML (y 7) Si el cliente es.net, puede usar System.Web.HttpUtility encodedvalue = HttpUtility.UrlEncode(value, System.Text.Encoding.UTF8); Cuando se utiliza el navegador como cliente (para pruebas), hay que realizar la conversión a mano si el navegador no lo hace automáticamente E.g. En Firefox 2 para hacer la petición GET del ejemplo anterior habría que introducir http://.../xmlservice?par1=1&par2=hello+world E.g. En Firefox 3 sería posible introducir http://.../xmlservice?par1=1&par2=hello world En el lado servidor (en la clase página) no hay que realizar la decodificación La decodificación de los valores de los parámetros HTTP la hace automáticamente el contenedor de servlets 12
AJAX Introducción a AJAX El apartado 4 del enunciado de la práctica introduce el concepto de AJAX Ajax: A New Approach to Web Applications: http:// www.adaptivepath.com/ideas/essays/archives/000385.php http://www.tic.udc.es/~fbellas/teaching/is-2007-2008/ IntroduccionAJAX.pdf (transparencias 1-13) AJAX en Tapestry Screencast de Howard Lewis Ship demostrando cómo usar el componente Zone: http://tapestryjava.blogspot.com/ 2008/11/tapestry-5-ajax-screencast.html http://tapestry.apache.org/tapestry5/guide/ajax.html 13