Vaadin é um framework para criar aplicações web ricas (RIA) que usa os componentes do GWT e mapeia os eventos para o servidor, ou seja, abstrai o mapeamento dos serviços do GWT.
Uma aplicação em Vaadin
Basicamente uma aplicação web com Vaadin é bem simples:
import com.vaadin.ui.*; public class HelloWorld extends com.vaadin.Application { public void init() { Window main = new Window("Hello window"); setMainWindow(main); main.addComponent(new Label("Hello World!")); } }
Baixe o vaadin-6.2.3.jar, coloque dentro do lib e configure o web.xml:
<context-param> <description>Vaadin production mode</description> <param-name>productionMode</param-name> <param-value>false</param-value> </context-param> <servlet> <servlet-name>Myproject Application</servlet-name> <servlet-class> com.vaadin.terminal.gwt.server.ApplicationServlet </servlet-class> <init-param> <description>Vaadin application class to start</description> <param-name>application</param-name> <param-value> HelloWorld </param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Myproject Application</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
Sua aplicação funcionando:
Integrando com o Spring
Estendi a classe AbstractApplicationServlet, que é uma servlet que indica qual a classe Application será usada.
package br.com.dev.naskar.integ.vaadin.spring;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
/**
* Inicializa o Spring e configura a application do Vaadin.
*
* @author rafael
*/
@SuppressWarnings("serial")
public class SpringVaadinApplicationServlet extends AbstractApplicationServlet {
/**
* nome do bean do spring que sera usado como application.
*/
private String nameSpringBeanApplication;
/**
* Class do application.
*/
private Class applicationClass;
/**
* Contexto do spring.
*/
private ApplicationContext springContext;
@Override
protected final Class getApplicationClass()
throws ClassNotFoundException {
return applicationClass;
}
@Override
public final void init(final ServletConfig config) throws ServletException {
super.init(config);
nameSpringBeanApplication =
config.getInitParameter("nameSpringBeanApplication");
String contextConfigLocation =
config.getInitParameter("contextConfigLocation");
if (contextConfigLocation == null || contextConfigLocation.equals("")) {
throw new RuntimeException(
"Parametro contextConfigLocation nao configurado: "
+ contextConfigLocation
);
}
springContext =
new ClassPathXmlApplicationContext(contextConfigLocation);
Application application =
(Application) springContext.getBean(nameSpringBeanApplication);
if (application == null) {
throw new RuntimeException(
"Spring Bean nao encontrado: " + nameSpringBeanApplication
);
}
applicationClass = application.getClass();
}
@Override
protected final Application getNewApplication(
final HttpServletRequest request
) throws ServletException {
return (Application) springContext.getBean(nameSpringBeanApplication);
}
}
A cada HttpSession criada para um usuário, é chamado o método getNewApplication, ou seja, precisamos lembrar sempre de configurar o bean com escopo de prototype, para que a cada get do contexto do Spring, seja criado uma nova aplicação.
package br.com.dev.naskar.apres;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.vaadin.Application;
import com.vaadin.ui.Label;
import com.vaadin.ui.Window;
/**
* Blank application.
*/
@Component
@Scope("prototype")
@SuppressWarnings("serial")
public class BlankApplication extends Application {
/**
* Mostra a iniciacao da aplicacao.
*/
public BlankApplication() {
System.out.println("Iniciando application...");
}
/**
* Cria o layout da janela principal.
*
* @return Janela principal.
*/
public final Window crieWindow() {
Window mainWindow = new Window("Blank Vaadin Spring");
Label label = new Label("Hello Vaadin Spring!");
mainWindow.addComponent(label);
return mainWindow;
}
@Override
public final void init() {
this.setMainWindow(crieWindow());
}
}
Nessa classe podemos usar as injeções, aspectos, ferramentas de teste e tudo que o Spring tem sem problemas.
Veja que temos que trocar a definição da servlet, indicando qual o nome do bean do spring será usado e o onde está o applicationContext.xml do Spring.
<context-param> <description>Vaadin production mode</description> <param-name>productionMode</param-name> <param-value>false</param-value> </context-param> <servlet> <servlet-name>main</servlet-name> <servlet-class>br.com.dev.naskar.integ.vaadin.spring.SpringVaadinApplicationServlet </servlet-class> <init-param> <description>nome do bean do spring</description> <param-name>nameSpringBeanApplication</param-name> <param-value>blankApplication</param-value> </init-param> <init-param> <description>nome do bean do spring</description> <param-name>contextConfigLocation</param-name> <param-value>META-INF/applicationContext*.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>main</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
Pronto, temos a aplicação funcionando com todo o backend do Spring.
Conclusão
Estive procurando um framework para a camada de apresentação que não me desse tanto trabalho com detalhes da própria web. Utilizei o JBoss RichFaces, IceFaces (que é o que recomendo se você precisa mesmo usar JSF), mas vieram os problemas inerentes da própria API do ciclo de vida dos managed beans que o JBoss Seam resolveu muito bem com os seus escopos de conversação, mas que de vez em quando dá um nó na cabeça pra entender o fluxo de uma aplicação mais complexa.
Então, pesquisando no velho e bom google encontrei o Vaadin, que é tão simples quanto usar swing ou SWT. A princípio pensei que seria um framework mais orientado ao JavaScript como o Echo, SmartClient, etc. Adoro os protótipos e os ponteiros de função do JavaScript, mas a questão que você não trabalha sozinho num projeto e contratar ficar mais complicado.
Seguindo para a camada de negócio, Spring já um framework maduro e robusto, e que sinceramente, mesmo com o EJB 3.1 e a tendência de aplicações stateful (JBoss Seam), acho que a maioria das aplicações podem ser desenvolvidas com ele sem problemas (stateless). E com o lançamento do Spring Integration, as integrações entre sistemas não precisaram ficar exportando JAX-WS para tudo que é lado e tendo problemas de performance com XML até o ponto de lançarem hardware específico pra isso (WebSphere DataPower Integration Appliance).
Enfim, Vaadin é simples para apresentação e Spring é Robusto.
Em algum futuro post quero vê se coloco o HiIbernate Validator como Validator do Vaadin.
Referências
O código está no Gitorious:
http://gitorious.org/naskar/springvaadinblank/trees/master
Git: git://gitorious.org/naskar/springvaadinblank.git