miércoles, agosto 15, 2007

YA SAN CASAOOOO, YA SAN CASAAAOOOO...

Pos eso, que Marivi y Manolo, socios de N-Idea Soluciones y colaboradores de este blog ya han hecho su roce oficial y se casaron el sábado pasao. Dentro de poco editaré esta entrada con alguna foto ilustrativa de la efeméride.

La fiesta insuperable, la novia guapísima y el novio mu elegante, la comida insuperable (por lo menos la mía), y hasta las mil y pico de la madrugá bebiendo, cantando, bailando y gritando "¡¡Vivan los novios!!" y demás alaridos propios del casamiento. Especialmente gracioso era el gesto de Manolo cada vez que gritaban "¡Viva el novio!" que se rodeaba y hacía el gesto de la "v" con los dedos a tol mundo.

Pos eso, que pa bodas la de Marivi y Manolo. De lo único que nos quedamos con ganas es de haber escuchao cantar más a la madre de Marivi, que ya tendrá ocasión de deleitarnos más si cabe en alguna otra ocasión.

Por mi parte, me levanté al día siguiente con un pestazo a bizcocho de chocolate que algún desalmao me restregó por la cara y que esperaré a la siguiente boda familiar pa devolvérsela ;).

Y ná más, ¡¡¡¡VIVAN LOS NOVIOS!!!! ...y a ver si montáis más fiestones como ese que estaremos esperándolos con muchas ganas.

jueves, julio 12, 2007

Frameworks para RIAs

En esta cuarta entrega del desarrollo basado en Ajax, nos vamos a centrar en los diferentes frameworks existentes que nos pueden ayudar en nuestros desarrollos. Si no os habéis leído los posts anteriores, os recomiendo que os los leáis para entender mejor este:
En este post vamos a ver diferentes alternativas de las que disponemos para agilizar nuestra tarea (otra gente se ha pegado con el teclado por nosotros). Vamos a ver, aunque existen muchísimos más, los siguientes:
  • YUI: Yahoo User Interface, framework de Yahoo (que listo soy) para aplicaciones ricas de internet (RIA: Rich Internet Application). Muy completo y con un montón de ejemplos y documentación.
  • Dojo: Framework de la Dojo Foundation. Es también muy completo, quizás un poco más sencillo de utilizar que el de Yahoo y menos pesado para el explorador, aunque con menos documentación.
  • GWT: Google Web Toolkit. Es la implementación que da Google para Ajax sobre Java. En realidad, la filosofía de GWT es la de programar en Java y él interpreta el código Java para generar las páginas con los controles AJAX.
  • AJAX ASP.NET: La implementación para asp.net de AJAX. Incluye, aparte del core de librerías de comunicación una librería de controles llamada Atlas Control Toolkit. Se puede utilizar aunque no se utilice asp.net.
Todas estas librerías son de libre distribución. Por supuesto, existen muchas librerías de pago con controles flipantes que casi te programan la aplicación solas, pero los currelas de a pié, nos conformaremos con éstas (de hecho son muy buenas todas). Personalmente, la que más uso (todos los días) es la de ASP.NET, que hace cosas muy chulas. Tened en cuenta que en lo que más dan estos frameworks son controles para hacer nuestras aplicaciones más interactivas. Pero, vamos al tajo:

Yahoo User Interface:
Esta fue la primera librería que utilicé en mis pruebas. Tiene varias cosas muy buenas a tener en cuenta:
  • Una documentación muy buena con unas cheatsheets muy curradas.
  • Un mogollón de ejemplos con el código bien puesto.
  • Muchos controles
  • El respaldo de una gran empresa que soporta el proyecto (no te van a dejar tirado).
Cosas negativas que he visto y comprobado:
  • Puede llegar a ser bastante pesado para el cliente (las librerías javascript)
  • Es el framework más complejo con el que trabajar debido a que puedes hacer lo que quieras con él.
Este conjunto de librerías las puedes utilizar donde quieras porque son Javascript puro. De hecho, puedes mezclar diferentes librerías. ¿Os acordáis del ejemplo que puse en una de las entregas en el que se ponía el nombre y el servidor devolvía "Te devuelvo tu nombre: " y el nombre? Os acordéis o no, aquí tenéis ese mismo ejemplo pero implementado con YUI:

http://www.nidea-soluciones.com/PruebasAjax/YUI/yui1.html

El código javascript utilizado se divide en dos partes: primero tenemos que importar los scripts de YUI que vayamos a utilizar (lo miramos en su web para saberlo) y después realizamos nuestros propios scritps:







Los scripts a importar dependerán de qué es lo que vamos a utilizar de la librería de controles de Yahoo. En la página web se indica para cada caso cuáles son necesarios. La parte de programación es la siguiente:
















El meollo se encuentra en la línea YAHOO.util.Connect.AsyncRequest() que es la que crea el objeto XMLHttpRequest y realiza la llamada. Se le pasa el método, la url y una variable que contiene toda la información relativa a la función si va todo bien, la función si no va bien, los argumentos, etc. Es muy importante el orden, no podemos definir la variable callback antes de las funciones que manejarán las respuestas, ni podemos definir la variable callback después de la llamada al servidor.

Utilizamos también uno de los controles de YUI, el container en su versión panel. La programación con YUI se puede realizar de dos maneras distintas, por marcación o por Javascript. Todos los controles se pueden definir directamente en Javascript (caso del ejemplo) o definir en HTML (Markup). Al definir por HTML, cuando se llama al método render, la librería busca determinadas clases css y las convierte en controles. El mismo panel que se define en el ejemplo con HTML sería:











La librería lee las clases y las renderiza en pantalla en forma de panel.

Framework Dojo:
Este es el siguiente framework con el que trabajé. Tiene otras ventajas e inconvenientes que el YUI. Los que encontré fueron los siguientes:

Cosas buenas:
  • Un montón de controles
  • Definición en la programación más intuitiva que la de YUI.
  • Menos importaciones a nuestras páginas
Cosas malas:
  • La documentación es mucho peor.
  • Existen menos ejemplos en la utilización de los diferentes controles.
Veamos un ejemplo. Os he puesto el mismo ejemplo que con YUI pero programado con Dojo. Lo podéis ver en:

http://www.nidea-soluciones.com/PruebasAjax/Dojo/dojo1.html

El estilo de programación varía ligeramente entre ambos frameworks. En ambos disponemos de una parte de inicialización de dependencias que en el caso de YUI es mediante la incorporación de scripts y mediante Dojo se realiza más al estilo Java o C#:







Lo primero es importar la librería base dojo.js y después utilizamos la sentencia para importar aquellas partes que vayamos a utilizar. Podemos utilizar una sintaxis del tipo dojo.require() dojo.require("dojo.widget.*"); para importar todos los widgets. En este caso, como sólo vamos a utilizar el tipo Dialog pues lo importamos. La sentencia djConfig = {isDebug:true}; nos permite sacar mensajes de debug o de error en la librería por pantalla.

Dojo se diferencia de YUI en que al definir los elementos HTML, introducimos un nuevo parámetro llamado dojotype en el que le indicamos qué tipo de elemento dojo va a ser. De esta forma al inicializar el elemento en Javascript, la mayoría de la definición se encuentra en el elemento HTML. Vayamos por pasos: paso 1, el código HTML:
























En el código definimos tres divs a los que les decimos que son dojotype="dialog". De esta forma, Dojo sabe que tiene que renderizarlos como diálogos. Además les definimos una serie de características propias de Dojo (las subrayadas en rojo): bgcolor(color de fondo de la pantalla no del div), bgOpacity(opacidad del fondo de la pantalla), toogle (forma en la que aparece o desaparece la pantalla) y toogleDuration (duración del efecto de aparecer y desaparecer).

El resto del código es html normal. Veamos cómo se definen los diálogos y las funciones (ved que llamo a dos funciones Javascript CargarNombre() y Empezar()).
























He dividido el Javascript en trozos. En la primera parte tenemos las definiciones de las variables que vamos a utilizar después, los tres diálogos, y las dos funciones manejadoras de los eventos de respuesta correcta y respuesta incorrecta, hasta aquí todo igual que antes. Tenemos también la función init, que se ejecuta al cargar la página que define el primer diálogo que aparece en pantalla. La definición es muy simple, solamente utilizamos la sentencia dojo.widget.byId() y le pasamos el id del div que va a ser el diálogo (ese div tiene que tener el dojotype="dialog"). Le definimos el botón que va a ocultar el diálogo con la sentencia setCloseControl(). Ved que podemos utilizar con los diálogos las sentencias show() y hide() para mostrarlos u ocultarlos desde cualquier parte del código. ¿Y las llamadas a servidor cómo se hacen? Pues veamos el resto del código:
















Tenemos la función CargarNombre() que muestra el diálogo de espera y llama al servidor. Con Dojo, las llamadas se realizan utilizando el método dojo.io.bind al que le pasamos parámetros. Los más comunes y necesarios (algunos) son: url (dirección a la que llamar), load (método que controlará la respuesta correcta del servidor), error (método que manejará la respuesta de error del servidor), mimetype (mimetype de los datos de la llamada).

Dojo también permite realizar llamadas cross-domain mediante el método bind(), pero hay que importar el espacio dojo.require("dojo.io.XhrIframeProxy"), proque la llamada se realiza mediante un iFrame Proxy. Esto está aún en pruebas así que os aconsejo que vayáis a la documentación y os lo leáis.


Conclusión (hasta la próxima):
Como se me está haciendo demasiado largo el post, dejaremos los dos frameworks restantes para el siguiente. Sólo comentaros mi experiencia con ambos: personalmente prefiero el framework de Dojo que es bastante más intuitivo de utilizar, aunque YUI tenga más documentación (es realmente buena), cuando empiezas a trabajar con Dojo y te empiezas a enterar de cómo funciona, es más liviano. De todas formas, al ser frameworks completamente independientes de plataformas, siempre podéis conjugarlos y utilizar aquellas partes que más os gusten de uno y de otro.

Proximamente: GWT y ASP.NET AJAX

miércoles, julio 11, 2007

Noticiones Varios

Actualización:
Ya he arreglado el bug del mapa, así que podéis disfrutar de él todo lo que queráis. ¿Qué os parece?


Bueno chavales, hemos cambiado nuestra página web, dándole un nuevo aspecto. La podéis visitar en http://www.nidea-soluciones.com.

Aunque todavía tenemos que darle un último retoque, os recomiendo visitar la parte de contacto y abrid el mapa. Nos hemos integrado con el API de Google MAPS y ha quedado resultón. He detectado un pequeño bug que corregiré en breve.

Por otro lado, SUPER NOTICIA, Producciones Porunbujero ha empezado su actividad como estudio de grabación y productora de vídeos. Estamos trabajando en su página web, podéis visitarla (sólamente está la portada) para obtener los datos de contacto. Su dirección es: http://www.porunbujero.com

Os doy sus datos de todas maneras:

Producciones Porunbujero
Tejuela 25, Alcalá la Real
605978242

domingo, julio 08, 2007

Creación de un EJB(I): Session Bean

Bueno, después de este pequeño traspiés con la nueva versión de J2EE, voy a ir contándoos lo que voy haciendo para crear un bean de sesión desde donde lo dejé. Recordemos que en el primer post hablamos sobre la tecnología J2EE y en el segundo post habíamos instalao nuestro servidor de aplicaciones de Sun. Por lo que me comentó Manolo, existe también otro servidor de aplicaciones llamado JBOSS que parece ser que es más eficiente, pero como yo ya había trabajao con una versión previa de éste, os voy a contar cómo se hace ésto. También he visto por ahí que hay un proyecto open source llamado GlashFish que creo que también es un servidor de aplicaciones y tiene buena pinta pero eso es arena de otro costal que ya urgaremos cuando proceda. Yo voy a lo mío.

Después de instalar el servidor de aplicaciones, en la nueva versión, necesitamos para desplegar nuestras aplicaciones un pack para Netbeans o un plugin para eclipse que se ofrecen junto con el servidor de aplicaciones en la página de Sun. Ésas eran las herramientas que se descargaban si en vez de pulsar en Download with JDK pulsábamos en Download with Tools. Como por entonces no tenía ni idea de que ya no existía la herramienta de despliegue deploytool, pues yo ya tengo mi servidor de aplicaciones instalao en mi máquina. No todo está perdido. Yo he escogido hacerlo con NetBeans como reto personal porque ya conocía Eclipse y tenía ganas de ver qué tal era NetBeans, pero vosotros podéis hacerlo con lo que elijáis.

Bien, para empezar nos vamos a la página de descarga de Sun y pinchamos en un link que hay a la derecha en un div azul titulado Related Resources y que se llama NetBeans. Ahí podemos descargarnos tanto el propio IDE NetBeans como el Enterprise Pack. Descargad agusto. Luego la instalación es bastante simple. Hacemos un chmod +x fichero_binario y luego un ./fichero_binario. Con ésto se nos abre un instalador gráfico bastante intuitivo al que la máxima información que tendremos que aportarle será el sitio donde queremos que lo instale cuando se trate del IDE o del sitio donde hemos instalao el IDE cuando se trate del Enterprise Pack. Habrá un momento de la instalación que nos preguntará si queremos instalar un servidor de aplicaciones o si queremos usar una instalación preexistente. Obviamente aquí usaremos el servidor que habíamos instalao en el post anterior y para ello tendremos que darle el nombre de usuario y la contraseña de administrador que nos creamos en su momento.

Aparte de ésto, lo demás no os creará problemas. Y bien, ahora tenemos nuestro servidor de aplicaciones perfectamente sincronizao con nuestro IDE NetBeans que hemos instalao para el desarrollo de nuestros beans y sólo nos queda desarrollar las aplicaciones.


Creación de un Bean de Sesión - El meollo.

Vamos a crearnos un Bean de Sesión que a partir de un día, mes y año de nacimiento calcule la edad que debe tener la persona. Además posteriormente y para ver la funcionalidad de ésto, nos vamos a crear una página JSP que haga uso de este Bean para recoger la información introducida por un usuario, mandársela al bean, recoger el resultado y mostrarlo por pantalla. Al lío pues.

Arrancamos NetBeans si no lo hemos hecho ya y pinchamos en Archivo -> Nuevo Proyecto -> Nueva Aplicación Empresarial. Rellenamos los campos necesarios. En nuestro caso le vamos a poner de nombre CalculadorEdad. Ponemos la carpeta donde queremos que se guarde y seleccionamos la versión de J2EE que queremos usar. En este primer post vamos a usar J2EE 1.4 que es la versión que yo había trabajado, pero a ver si más adelante os puedo escribir cómo hacerlo con J2EE 5 para que veáis la diferencia. Aseguráos antes de darle a "Terminar" de que marcáis las casillas de "Crear módulo EJB" y "Crear módulo de aplicación Web" y dejad sin marcar la de "Crear módulo de aplicación Web" de abajo que se refiere a un cliente de aplicación web que nosotros no necesitaremos, sólo los dos primeros. Debería quedar parecido a lo que sigue:

Pinchad en "Terminar".

Ahora creamos el nuevo Session Bean. Para ello le damos al botón derecho en CalculadorEdad-ejb -> Nuevo -> Bean de sesión.
Introducimos el nombre que será CalculadorEdad, ponemos el nombre de un paquete, que será por ejemplo "calculadoredad". Marcamos "sin estado" puesto que vamos a hacer un Stateless Session Bean, ponemos el tick en las dos interfaces, remota y local y pinchamos en Terminar. En realidad podríamos valernos sólo con la Remota, ya que la local es para optimizar accesos desde local pero vamos a ponerlo todo y así vemos todas las interfaces en pleno rendimiento. El resultado será que nos creará automáticamente las clases que necesitamos e implementará él sólo el código aburrido de los métodos de ciclo de vida y demás asuntos escabrosos. A nosotros nos tocará entonces implementar los métodos de negocio que son los específicos de nuestro bean. La intención es crear una aplicación que introduciendo una fecha de nacimiento calcule los años que tiene la persona dada. Así pues, nuestro método de negocio lo llamaremos edad y recibirá como parámetros 3 int representando el día, mes y año de nacimiento. Además le diremos que lanza una excepción que llamaremos PeroQueInventoEsEsteException y que extiende de Exception para indicar cuando alguien ha introducido una fecha no válida (ya se que aún no la hemos creado, lo haremos a continuación).

Si le damos al botón derecho en la clase CalculadorEdadBean , y seleccionamos métodos EJB -> Agregar método Business podremos añadir nuestro método de negocio que os describía arriba y el código se implementa sólo. Jurch, estos IDEs...dentro de poco no habrá que saber programar para programar :).

Justo después de haber puesto todo lo que arriba decíamos vamos a crearnos nuestra excepción especial. Para eso nos vamos dentro de CalculadorEdad-ejb al apartado de "Paquetes de orígen". Le damos al botón derecho encima y decimos Nuevo -> Clase java. Como nombre le damos PeroQueInventoEsEsteException y le decimos que la cree. A continuación la abrimos haciendo doble click en ella y añadimos a su declaración de clase el código "extends Exception" para que tenga las propiedades de una excepción normal y corriente. Luego en el constructor por defecto metemos como código "super();" y nos creamos un constructor con un String como parámetro que tenga por código "super(motivo);" siendo motivo el nombre del String del parámetro. Ya tenemos nuestra excepción.

Ahora vamos a implementar el código de nuestro método de negocio. Para ello nos vamos a la clase CalculadorEdadBean que es quien tiene que implementar el código de nuestro bean y picamos código. Mi implementación to perrillera del método que calcula la edad es la que os pongo aquí.

public int edad(int dia, int mes, int anho) throws PeroQueInventoEsEsteException{
//Obtenemos un objeto java.util.Date con la fecha actual y un objeto java.sql.Date con la fecha que ha introducido el usuario
java.sql.Date fecha = java.sql.Date.valueOf(new Integer(anho).toString()+"-"+new Integer(mes).toString()+"-"+new Integer(dia).toString());
hoy = new Date();
//Para compararlos obtengo el número de milisegundos desde "The Epoch"
long nacimiento = fecha.getTime();
long actual = hoy.getTime();

//Si se ha introducido una fecha futura...
if(nacimiento>actual){
throw new PeroQueInventoEsEsteException("¿Tu tas creído que somos unos pardillos o qué? ¿usease que aún no has nacío no?");
}

//Calculamos el tiempo en milisegundos que la persona lleva viviendo y hayamos su edad averiguando cuántos años son esos milisegundos. Hay un error obvio debido a los años bisiestos pero no lo contemplaremos aquí.
long tiempoDeVida = actual-nacimiento;
int edad = (int)(((tiempoDeVida/1000)/3600)/24)/365;

return edad;
}


Hago uso de java.util.Date (que está importada en el inicio de la clase con un simple "import java.util.Date") y de java.sql.Date por la facilidad de uno para crear objetos Date a partir de Strings y la facilidad del otro para crear objetos Date representando la fecha actual. Como ambos tienen un método getTime() que devuelve el número de milisegundos desde "The Epoch" que es como se conoce a las 00:00h del 1 de enero de 1970, mediante una simple resta puedo tener los milisegundos de vida de la persona que ha introducido su fecha de nacimiento. Paso los milisegundos a años y voilà, ya tenemos su edad. Está claro que no estoy contemplando los bisiestos y ésto sería un problema, pero como la propia implementación es bastante perrillera no me voy a centrar en que el código sea bonito o que cumpla bien con su cometido, sino en que veáis una implementación de un EJB. Además la aproximación es bastante cercana, y sólo fallará en días próximos a nuestro cumpleaños así que lo podemos considerar aceptable para un ejemplo :). De toas formas sí, ya se que es un código un tanto perrillero, pero weno, qué le vamos a hacer.

Lo único que nos queda por hacer con el Bean es darle un nombre de referencia en el servidor para que pueda ser encontrado por nuestra página web (que crearemos a continuación) cuando vaya a buscarlo. Ésto es fácil. Nos vamos al menú de la izquierda, donde está nuestro CalculadorEdad-ejb. Desplegamos el submenú "Archivos de configuración" y hacemos doble click encima de "sun-ejb-jar.xml". Ese fichero es en realidad un xml, pero nuestro querido IDE NetBeans nos lo mostrará como cajitas y menús tó wapos (si es que vivimos en una puta metáfora con las interfaces gráficas ;) ). Veréis que debajo de "Configuración Sun" tenéis un submenú llamado CalculadorEdadBean, pues pinchad en él, y veréis algo como ésto:


Rellenadlo como véis en la imágen, poniendo "ejb/CalculadorEdadBean" en el campo de "Nombre JNDI". Ya tenemos nuestro bean programado y reconocido por el servidor para que pueda ser llamado por otras aplicaciones, servlets, beans o JSPs.

Ahora nos vamos a crear una página JSP. En realidad esta página ya está creada. Se creó automáticamente cuando marcamos la casilla de "Crear módulo de aplicación Web" cuando creamos el proyecto. Para verla, id en el menú de la izquierda a "CalculadorEdad-war" y desplegad su submenú. De ahí nos vamos a páginas web y veréis que hay una que se llama "index.jsp". Ésta es la que nuestro servidor de aplicaciones mostrará cuando ejecutemos la aplicación y entremos en localhost:8080/CalculadorEdad-war. Pinchad dos veces sobre ella y se os abrirá a la derecha. Ahora la vamos a editar. Os voy a enseñar el código en dos trozos pa ir explicándooslo poco a poco. Primer cacho:


De lo que veis, llamaros la atención sobre unas pocas cosas:
  • No os olvidéis de importar las clases necesarias para el funcionamiento de vuestra página JSP, además de las clases de las interfaces del Bean que váis a usar.
  • Cread un contexto inicial como se ve en el código.
  • Fijáos en la forma de obtener una referencia a nuestro Bean. Primero se obtiene una referencia al interfaz de inicio o interfaz Home de nuestro Bean sobre la que llamaremos a su método create(). Lo hacemos con el método lookup(String) sobre nuestro contexto inicial y le preguntaremos por "java:comp/env/" + el nombre que le dimos a la referencia del EJB. ¿Os acordáis? Lo que sí recordaréis seguro es que en los Session Beans el bean nace y muere con el cliente, así que aquí no tendría mucho sentido obtener la referencia de otra forma. La creamos cada vez y punto.

Ahora pasamos al segundo cacho:


Aquí está la chicha de nuestra página. Quitando el código que es meramente HTML, lo más importante quizás sea lo que está a partir de la línea 47. Tened en cuenta que cuando llamemos a nuestra página JSP lo podremos hacer pasándole parámetros en la propia URL del tipo dia=4&mes=5&anho=1984. Ésta es la forma de funcionar de una petición "GET". Para recuperar esos parámetros en nuestro JSP tendremos siempre el objeto request siempre inicializado y que indica la petición, y si llamamos a su método getParameter("parametro"), éste nos podrá devolver o el valor del parámetro, o bien null, y debemos contemplar esa posibilidad. También contemplamos la posibilidad de que el usuario pinche sobre el botón sin haber introducido nada (se hace en las comprobaciones noseque.length()>0) por lo que se estará enviando una cadena vacía. Una vez capturados los parámetros con los que se ha llamado a nuestra página JSP mediante nuestro formulario que generaba peticiones "GET" sobre la propia página, los transformamos en el tipo de dato que necesitábamos, para ello apoyándonos en la clase java.lang.Integer y llamamos al método de negocio edad(int,int,int) que nos habíamos creado usando la referencia que obtuvimos en el primer cacho de código. Al realizar la llamada tenemos que encapsularla por un try-catch que recoja las excepciones que se puedan producir, que en nuestro caso será la excepción especial cachonda que nos habíamos creao. Y finalmente, si la excepción no se ha producido sólo tenemos que mostrar el mensaje con el resultado de la llamada a nuestro bean. ¿A que no es complicao?

Por último, vamos a crear una referencia al EJB en nuestro módulo de aplicación web. Cosa sencillica. Nos vamos al menú de la izquierda de NetBeans. Desplegamos el menú de "CalculadorEdad-war" y dentro de él el submenú de "Archivos de configuración". Hacemos doble click sobre web.xml. Aquí pasa como antes, que pese a que es un fichero xml, nuestro IDE nos lo muestra de forma bonica (si queréis ver su forma real podéis pinchar en el botón "XML" que os lo enseñará perfectamente). Ya trastearéis un poquillo por este fichero para descubrir que se pueden configurar muchísimas cosas, como por ejemplo el tiempo que dura una sesión o temas de seguridad y demás, pero lo que a nosotros nos importa lo conseguimos pinchando en el botón de "Referencias". Ahí desplegaremos "Referencias EJB" y pincharemos sobre "Agregar". Ahí se os mostrará algo como:


Rellenadlo como ahí pongo. Aquí fijáos que en el nombre de la referencia tiene que haber una coherencia con el nombre que configuramos antes en el servidor al EJB. Luego, dado que hemos metido las distintas clases de nuestro EJB en un paquete llamado calculadoredad, fijáos en que al indicar las interfaces de inicio y remota hemos puesto delante calculadoredad.*, es importante. Una vez que hayáis hecho ésto, pinchamos en guardar y tocad la madera más cercana porque se supone que ya lo tenemos todo listo para desplegar nuestra aplicación. Lo que sigue es fácil. Le damos al botón derecho encima de "CalculadorEdad", que es la raíz de nuestro menú de la izquierda y seleccionamos "Ejecutar Proyecto". Nos saldrán un chorro de letras por abajo, os pedirá el nombre de usuario y contraseña de administrador y parecerá que nuestra máquina esté intentando calcular todos los números de pi, pero cuando lleve un rato leeréis algo así como "GENERACIÓN CORRECTA" y sabréis que todo este tiempo habrá merecido la pena :). Que no os lleve a engaños, este mensaje aparece también cuando la mayoría de las cosas fallan. Depende del tipo de fallo que se produzca. Si las referencias las habéis puesto mal o el código no rula como debería de rular, el mensaje os aparecerá, pero cuando intentéis entrar en vuestra página lo que salga o cómo funcione la aplicación...eso ya será otro rollo.

Para comprobar que la cosa rula abrimos un navegador y metemos la dirección
http://localhost:8080/CalculadorEdad-war/
Si todo ha ido medianamente bien debería de mostrársenos algo como ésto...


Ahora introducimos un día de nacimiento, mes y año correctos, por ejemplo Día: 4, Mes: 5, Año: 1984, y pinchamos en "Submit". Nos debería salir algo como...

Es correcto. Pero, ¿qué pasa si introducimos una fecha en el futuro? ¿cómo manejará nuestra página aquella PeroQueInventoEsEsteException que nos inventamos? ¡Probémoslo! El resultado debería parecerse a éste...


Wapo ¿verdad?. En realidad, seguramente no queráis hacer una aplicación de un servidor de aplicaciones que maneje una página que te calcula tu edad con un cierto márgen de error de días según bisiestos...es mu probable que no, pero hacer un calculador de edad es lo mismo que hacer cualquier otra cosa, sólo cambiad el código y número de los métodos de negocio y fenómeno. Se que es un poco tedioso, pero también hay que tener en cuenta que en este ejemplo nosotros hemos hecho todo el trabajo. En un servidor de aplicaciones real seguramente no tuviéramos que hacerlo. Ahí es donde entra el reparto de roles que contempla este tipo de programación. El desarrollador no tiene por qué ser el mismo que el desplegador, que a su vez no hace falta ni que conozca a quien montó el servidor de aplicaciones. Por eso os enseñé en el anterior post cómo arrancar y parar el servidor desde línea de comandos, pues puede que os toque símplemente hacer ésto y no desarrollar nada encima. Una vez montado el sistema, ya es sólo cuestión de hacer correr distintas aplicaciones sobre él y si somos listos al cliente le cambiaremos muy poco la interfaz para no hacerle la picha un lío, como al fin y al cabo lo que va por debajo no le importa, sólo tenemos que añadir métodos de negocio y añadir nuevas funcionalidades en nuestra interfaz que nunca cambia :). Todo ventajas. Inconveniente: ésto es java, así que ya se sabe, el procesador echando humo y la memoria derrochándose. Pero weno, dejemos eso para otro momento.

El desarrollo de un EJB de sesión con estado es bastante similar al del sin estado que hemos desarrollado así que el siguiente post lo dedicaré a crear un EJB de entidad (con una bonita base de datos derby). Espero no haberos aburrido mucho y que ésto os pueda servir para introduciros en cómo hacer lo que ya sabéis que queréis hacer.

martes, julio 03, 2007

AJAX PARA SUPERCAMPEONES o ¿Sabremos alguna vez qué es AJAX? (III)

Hala, de vuelta con el tema Ajax (la verdad es que da mucho juego el tema...). En esta tercera entrega de esta serie nos vamos a centrar en los siguientes dos temas:
  • Llamadas simultáneas: es decir, realizar múltiples llamadas a diferentes sitios a la vez.
  • Llamadas asíncronas secuenciales: este es un tema importante, saber cómo hacer llamadas asíncronas de forma ordenada.
Si no os habéis leído los posts anteriores, os recomiendo que lo hagáis:
Como sé que ya te los has leído, Nacho, puedes seguir con el siguiente punto ;P. En este post, terminamos la serie de AJAX PARA CAMPEONES o AJAX A PELO o AJAX KAMIKAZE, es decir, ajax para frikies.

Llamadas simultáneas
Una de los beneficios más importantes de trabajar con hebras de ejecución es que podemos crear tantas como nos permita el entorno (hardware, línea de comunicación, etc.) y el objeto XMLHttpRequest no es menos. Trabajando con AJAX podremos, por lo tanto, lanzar mútliples hilos de comunicación de forma simultánea que ejecutarán tareas distintas. Tendremos que tener cuidado de manejar correctamente las respuestas, de forma que sepamos siempre de quién es cada una.

En el ejemplo que os pongo aquí, podéis realizar tres llamadas simultáneas para que se carguen en los divs inferiores la página web que hayáis puesto. No es que esté demasiado currado pero menos es nada.

Ejemplo: http://www.nidea-soluciones.com/PruebasAjax/PruebaAjax5.html

Existen ciertas peculiaridades para que este ejemplo funcione:
  • Se ha creado una nueva función EnviarPeticionConParametro que además de realizar la petición le pasa un parámetro a la función que maneja la respuesta (aparte del objeto XMLHttpRequest).
  • Se ha implementado un Proxy al que llama la página para que se puedan hacer llamadas asíncronas CROSS-DOMAIN. Ésto lo explicaré otro día.
El código de la nueva función es el siguiente:










Como veis, introducimos un nuevo argumento llamado "parametro" que se le pasará a la función callback. Con este parámetro podremos decirle a la función callback qué objeto es el que ha realizado la llamada y ha respondido. Lo marco porque es muy importante ya que cada llamada tardará el tiempo que sea y devolverá el resultado en orden aleatorio. Tenemos que disponer de algún método que asocie la llamada con la respuesta.

Para entenderlo mejor, veamos el código de la página y cómo se realiza la llamada:



















En este caso, tenemos la función CargaURL(posicion), donde en posición se le pasa un 1, un 2 o un 3, dependiendo de qué botón es el pulsado. En base a ese número, se leerá el input correspondiente y se mostrará el panel de espera asociado. Finalmente se llama a la función EnviaPeticionConParametro y se le pasa la posición como parámetro final.

A la función que maneja la respuesta le llega el parámetro de la posición por lo que es capaz de poner la respuesta en el div correcto y oculta el div de espera correspondiente. De esta forma podemos tener una sola función que gestiona todas las llamadas y otra función que gestiona todas las respuestas. Si no lo hiciésemos así tendríamos que asociarle una función diferente a cada respuesta.

Os pongo un dibujo que como sabéis me molan y en el post anterior no tuve oportunidad de poner ninguno:











Las peticiones se envían al servidor, el cual las gestionará y tardará un tiempo x. Al ser asíncronas, las peticiones se evaluarán de forma simultánea y a medida que las vaya resolviendo irá mandando la respuesta. El orden de evaluación y respuesta no es fijo por lo que el orden de llegada de las peticiones no tiene por qué tener relación con el de salida. Es muy típico equivocarse con este concepto y escribir lo siguiente:

function MiFuncionQueRealizaMuchasCosas(){
// Primera accion asíncrona
ActualizaDatos();
MuestraDatosActualizados();
}

Error, al ser la función ActualizaDatos una llamada asíncrona a servidor, perderemos ese hilo de ejecución hasta que lo recoja el manejador de la respuesta. Por esto, la función MuestraDatosActualizados() no mostrará esos datos.

Llamadas asíncronas secuenciales
Por fin, el último ejemplo, lo último del AJAX PARA CAMPEONES. Este ejemplo se lo dedico con mucho cariño a Nacho porque sé que es tela de friki del Linux y en especial de Kubuntu y Ubuntu. Espero que te guste.

Como ya estaba harto de páginas html guarras con el texto a pelote decidí currarme un poquillo más este último ejemplo del post. En este ejemplo se realizan seis llamadas a servidor secuenciales, hasta que no se recibe la contestación de una no se realiza la siguiente. Podéis ver el ejemplo en la siguiente dirección (funciona mejor con Firefox porque el IE, a partir de la segunda vez, se pasa por el forro el delay que le tengo puesto en servidor):

http://www.nidea-soluciones.com/PruebasAjax/PruebaAjax6.html

Mola cantidad, eh? Por lo menos le damos un poco de aqué al tema. En fin, vamos al lío. ¿Cómo se hace esto? Aparte del tema gráfico (cada uno lo pone como más le gusta), la secuenciación de llamadas se realiza de la siguiente manera (os lo pongo en tres imágenes porque no me cabía en una):


















































Lo que hacemos es lo siguiente:
  1. Cuando el usuario pulsa sobre el botón, mostramos el divProgreso y le ponemos la primera imagen grande y su texto. Llamamos a la url Codigos/PruebaAjax6.aspx para ir a servidor.
  2. Cuando se recibe la respuesta, se pone la imagen en pequeño, se pone en grande la siguiente y la descripción de la acción y se realiza la llamada a la página con el parámetro del siguiente paso.
  3. Así sucesivamente hasta que en la última llamada, invocamos a la página redireccion.html. Obtenemos su código html y lo metemos dentro del div wrapper que engloba a toda la página.
Viéndolo en un dibujillo:















Es en las funciones callback donde realizamos la siguiente llamada.

El finaaaal deeeel veraaanooooo, llegoooo.....
Como todo, en algún momento hemos de llegar al final e igual que el verano todo acaba. Creo que con esta serie de ejemplos cubrimos la base de la comunicación asíncrona y del AJAX PARA CAMPEONES. Como os habréis percatado, el manejo del Javascript es fundamental (por Dios, nooooo), aunque, como veremos en posts posteriores, existen frameworks que nos ayudarán en nuestro cometido (un poco). Es importante que os deis cuenta que es indiferente el lenguaje de programación que utilicéis (yo lo he hecho todo en html plano), simplemente debe permitir hacer llamadas a funciones Javascript.

En próximos capítulos:
  • Frameworks Ajax
  • Llamadas Cross-Domain
Se me está ocurriendo hacer también algún post con el tema de los Mash-Ups.