Introducción a Vaadin, un framework para RIA

Pues bien, hace poco el buen rugi (o @rugi si prefieren) publicó una liga a un framework para RIAs (Rich Internet Applications), llamado Vaadin, preguntando si alguien lo conocía o lo había usado. Yo jamás había oído hablar de él, así que me puse a revisarlo y después de ver el video introductorio me dio bastante curiosidad, así que ya me puse a programar algunas cosas con esto.

El desarrollo con Vaadin se centra en hacer aplicaciones solamente programando en Java; no es necesario manejar Javascript ni HTML para la mayoría de las cosas. Se pueden desarrollar componentes propios, basados en los componentes existentes de Vaadin, que van desde botones, etiquetas, ligas y campos de texto hasta formas completas, campos para captura de fecha, notificaciones de errores, árboles jerárquicos, etc.

Para componentes como listas de elementos, tablas y árboles, Vaadin ofrece un modelo de datos bastante flexible pero un poco engorroso de manejar, por el nivel de abstracción que manejan, aunque ofrecen algunas clases para mapear POJOs con las clases de su modelo de datos, lo cual facilita un poco las cosas.

La programación es similar a Swing, ya que el control de las acciones también se maneja por medio de eventos que son enviados a listeners. Esto simplifica un poco las cosas y ofrece una buena abstracción al grado de que se puede uno olvidar de que se está programando una aplicación para web. Es importante mencionar que Vaadin está basado en el Google Web Toolkit, usa varios componentes de este framework.

A continuación el clásico Hola Mundo en Vaadin, que presenta una página con una simple etiqueta:

package org.javamexico.ejemplo;

import com.vaadin.ui.Window;
import com.vaadin.ui.Label;
public AplicacionEjemplo extends com.vaadin.Application {

  public void init() {
    Window main = new Window("Ventana Principal");
    main.addComponent(new Label("Hola Mundo!"));
    setMainWindow(main);
  }

}

Cómo hacemos para que esto funcione? Pues bien, en el web.xml de nuestra aplicación, hay que configurar lo siguiente (no pongo el web.xml completo, solamente lo que hay que agregar):

        <!-- Esto es para mensajes de error, debug, etc -->
        <context-param>
                <param-name>productionMode</param-name>
                <param-value>false</param-value>
        </context-param>

        <!-- Aqui ponemos el servlet inicial de Vaadin y le indicamos nuestra clase de aplicacion -->
        <servlet>
                <servlet-name>Ejemplo</servlet-name>
                <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
                <init-param>
                        <param-name>application</param-name>
                        <param-value>org.javamexico.ejemplo.AplicacionEjemplo</param-value>
                </init-param>
        </servlet>

        <servlet-mapping>
                <servlet-name>Ejemplo</servlet-name>
                <url-pattern>/*</url-pattern>
        </servlet-mapping>

Me gustó que la config en web.xml es bastante simple, similar a Tapestry en el sentido de que solamente hay que poner el servlet principal y pasarle un par de parámetros. En este caso se indica la clase para la aplicacion y listo.

Spring + Hibernate

Por lo general en una aplicación web o RIA vamos a necesitar varios componentes como DAOs y algunas otras cosas para manejar nuestros datos, que pueden venir de una RDBMS o de algún otro lado. Un caso común es utilizar Spring y Hibernate; con un buen diseño, se tienen definidas interfaces para DAOs que son completamente separadas de Hibernate, y por otra parte se tienen las implementaciones de dichos DAOs usando Hibernate. Los DAOs se configuran como beans en un ApplicationContext de Spring y listo. Ahora la pregunta es, ¿Cómo podemos integrar Spring con Vaadin?

Estuve buscando y el framework como tal no ofrece algo para integrarse con Spring. Sin embargo no fue difícil, una vez que revisé la arquitectura. Una ventaja de Vaadin es que cada sesión va a tener sus propias instancias de los componentes que necesite, incluso de la aplicación, por lo que todo lo podemos poner como beans en Spring. Por ejemplo podemos crear un ApplicationContext donde nuestra clase AplicationEjemplo resida como un bean; configuramos Spring para web de la manera estándar (agregando el ContextLoaderListener en el web.xml e indicando los archivos XML en el parámetro de contexto contextConfigLocation).

Suponiendo que tuviéramos algunos componentes de Spring que queremos conectar a nuestra aplicación de ejemplo, nuestra app se podría ver así ahora:

public class AplicacionEjemplo extends Application {
  @Resource(name="ejemploDao")
  private EjemploDAO dao;
  @Autowired
  private OtroComponente comp;
  @Autowired
  private SimpleJdbcTemplate jdbc;
  @Resource(name="ventana2");
  private Window otraVentana;

  public void init() { /* etc */ }
}

Luego definimos un bean en el application context de Spring, algo así:

<!-- Es importante que este bean tenga scope=prototype -->
<bean id="main" class="org.javamexico.ejemplo.AplicacionEjemplo" scope="prototype" />
<!-- por aqui podrian estar los otros beans -->
<bean id="ejemploDao" class="org.javamexico.ejemplo.dao.EjemploDaoImpl" />
<bean class="org.javamexico.ejemplo.comps.OtroComponente" />
<bean id="ventana2" class="org.vaadin.ui.Window">
  <constructor-arg value="Segunda Ventana" />
</bean>

Y para poder usar Spring solamente necesitamos subclasear el ApplicationServlet:

public class VaadinSpringServlet extends ApplicationServlet {

  private org.springframework.web.context.WebApplicationContext appcontext;

  public void init(ServletConfig cfg) throws ServletException {
    super.init(cfg);
    appcontext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletConfig.getServletContext());
  }

  /** Obtiene el objeto de aplicacion configurado en Spring y devuelve una nueva instancia.
      Este metodo se invoca para cada nueva sesion, por eso es importante que se configure
      en Spring con scope=prototype para que cada llamada a getBean() genere una nueva instancia
  */

  @Override
  protected Application getNewApplication(HttpServletRequest request) throws ServletException {
    return (Application)appcontext.getBean("main");
    //O tambien podria ser asi, siempre y cuando solamente haya en Spring un solo objeto
    //configurado que sea subclase de Application
    //return appcontext.getBean(getApplicationClass());
  }

}

Lo anterior nos permite configurar la aplicación completa usando Spring, lo cual facilita bastante las cosas porque se pueden definir varios componentes, ventanas, controladores, etc en Spring y conectarlos ahí mismo para que solamente se tengan que invocar donde sea necesario, eliminando bastante código.

Bueno pues esto es una introducción muy ligera a Vaadin, si alguien tiene más curiosidad puede bajar el framework directamente de su página y jugar con él; el paquete que bajan contiene una demo con ejemplos de todos los componentes visuales, un libro en PDF con la documentación completa, ligas a los JavaDoc de todo el framework y algunas otras cosas. Es software libre bajo licencia Apache 2.0 lo cual permite su uso en aplicaciones comerciales.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de jali

Se ve interesante

Se ve bastante bonito el sitio, seria cosa de descargarlo y probar funcionalidades mas especificas. No se si siempre se comporte asi de lento/pesado
gracias por la info

Imagen de ezamudio

Depende del navegador?

Lo sentiste lento? Yo lo he estado usando y no lo he sentido pesado, uso Safari 4. Tal vez en otros se ve más lento (y en alguno se verá mejor).

Imagen de jali

Lo use con firefox

Pues no lo se, yo lo senti bastante lento en las peticiones. Puede ser el navegador de la maquina de mi chamba(win xp) por que lo acabo de probar en firefox 3.5.9 en ubuntu 64 bits y si esta mucho mas rapido. Sera cosa de probar con IE y Chrome a ver que tal no?

Imagen de ezamudio

IE?

Para qué probar con IE? Para lo único que sirve IE es para bajar Firefox.

Imagen de Jvan

Chrome

Con Chrome va que vuela :P

Imagen de Jvan

La misma filosofía que GWT

Se sigue la misma filosofía que en GWT? es decir, separar en paquetes client y server? y hacer RPC con tus servicios en el lado del servidor?? o cambia esa parte?

Imagen de jali

Sarcasmo

Era la parte sarcastica del comentario jajaja

Imagen de ezamudio

GWT

Hasta el momento con lo que he probado de Vaadin solamente he tenido que programar cosas del lado del server y con eso se genera la GUI del lado del cliente, bastante interactivo todo, sin tener que meterme a implementar nada del lado del cliente y eso que ya hice algunos componentes sencillos (algo similar a un JOptionPane muuuuuuy simple).