Mais um longo tempo sem postar aqui no blog. Não por falta de vontade, mas é que está dificil tirar um tempo para escrever.
Mas vamos ao que interessa, hoje vou falar um pouco sobre o meu primeiro contato com um dos mais famosos frameworks MVC para web: o Struts 2. Na empresa onde atualmente trabalho, estamos reestruturando praticamente tudo, desde a metodologia de trabalho até questões de arquitetura e APIs utilizadas. Se tratando de MVC, alguns frameworks foram elencados para serem estudados, sendo eles: Struts 2 e JSF. Em meus projetos particulares sempre utilizei o VRaptor como framework MVC, considero-o extremamente estável e produtivo, principalmente por seguir a idéia de Convention over Configuration. Porém, como o VRaptor foi (e é) desenvolvido pelos membros da Caelum, muita gente afirma que não é muito seguro utilizá-lo, pois o mesmo pode deixar de ser mantido e ficar obsoleto. Eu particularmente não acredito nisso nem um pouco, o VRaptor é opensource e já vem sendo utilizado por diversas organizações, inclusive de grande porte. A comunidade é ativa através do fórum (em português) e listas de e-mail do SourceForge (em inglês). Entretanto essas justificativas não foram suficientes para a equipe do meu trabalho considerar o VRaptor como opção, portanto começamos a estudar o Struts 2 (nossa primeira opção).
Primeiramente foram levantadas algumas features que considero importante em qualquer framework MVC que se diz “moderno” (e que estão presentes no VRaptor 2 :P), são elas:
- Configuração. Nenhuma, XML, Properties?
- Passagem de parâmetros através de Injeção de Dependências
- Interceptadores
- Validação
- View Redirection
- Outjection
- Ajax (retorno XML ou JSON)
- Plugins?
Configuração: O mecanismo de configuração do Struts 2 segue a idéia do WebWork. O principal arquivo é o struts.xml, onde definimos interceptadores, result types, actions, etc. A forma básica de configurar uma nova action no Struts 2 continua sendo inscrevê-la no struts.xml. Porém agora temos a vantagem de poder definir um método como sendo uma action, sem a necessidade de ter somente o método publico execute na classe. No site do Struts 2 encontrei também um plugin chamado Convention, que diz permitir o uso de anotações para configurar as actions, descartando o struts.xml. Porém não obtive sucesso no uso dele, mesmo seguindo exatamento os passos do tutorial.
Passagem de Parâmetros: A passagem de parâmetros para as actions é bem elegante no Struts 2. Ocorre a injeção de dependências por Setter, ou seja, todos os atributos das actions que tiverem setter podem ser acessados. A conversão de tipos ocorre de forma automática, por exemplo no parâmetro ?pessoa.nome=Germano o método setNome do bean Pessoa é invocado, sendo necessário também existir um método setPessoa na classe da action. O Struts 2 permite também a implementação de conversores customizados específicos.
Interceptadores: Os interceptadores do Struts 2 seguem a mesma idéia dos outros frameworks. A vantagem do Struts 2, com relação aos interceptadores, é que podemos definir a ordem que são executados. Podemos definir a ordem inclusive dos interceptadores inclusos na API do Struts, ou seja, podemos indicar um interceptador implementado na nossa aplicação para ser executado antes dos interceptadores padrões do struts, por exemplo. O Struts 2 possui também o conceito de pilha de interceptadores (Stack Interceptors), onde podemos definir a ordem de execução e reutilizá-la na definição de várias actions. O Strus 2 nos prove duas pilhas padrões, a defaultStack e a basicStack. A primeira é comumente usada em actions de submição de formulários, provendo interceptadores para realizar validação, e outras tarefas comuns. Já a basicStack é mais usada em actions de visualização, que são mais simples.
Validação: Baseado no conceito de DRY (Don’t Repeat Yourself), inicialmente fui atrás de um plugin do Struts 2 para integrar com o Hibernate Validation, porém não encontrei nenhuma solução oficial. A forma básica e padrão de definir validação no Struts 2 é através de XML (oh que novidade!) no struts.xml. Porém ele prove também uma forma de especificar as regras de validação em anotações a nivel de métodos (nas actions). Caso ocorra algum erro de validação, o Struts retorna ‘input’ como result type da action, onde através de view redirection (próximo tópico) podemos encaminhar para o formulário com todos os parâmetros enviados a action.
View Redirection: No Struts 2, todo método de action retorna uma String. Essa informação é usada para determinar qual a ação deve ser tomada após o término da action. Normalmente o fluxo é passado à uma página JSP para que seja gerado o conteudo HTML para retornar ao browser. Porém podemos definir um redirecionamento como resultado da action. O Struts permite tanto o redirecionamento no cliente (browser fazer uma nova requisição) quanto no servidor (na mesma requisição, mantendo todos os parâmetros da mesma). Para o redirecionamento no cliente deve ser usado o result type “redirect”, indicando a nova action a ser executada. Essa action é enviada ao browser para que seja feita uma nova requisição. Para o redirecionamento no servidor deve ser usado o result type “chain”, também indicando o nome da action a ser executada.
Outjection: Todos os métodos get contidos na classe da action são usados para colocar os valores no escopo da requisição e serem usados na View (via Expression Language na página JSP por exemplo). O Struts 2 permite também que façamos outjection para os escopos de sessão e aplicação, porém não através dos métodos get. Para realizar essa tarefa devemos acessar o método estático getContext da classe ActionContext e colocar os valores diretamente dentro da sessão ou aplicação, que são objetos do tipo Map.
Ajax: O Struts 2 possui suporte completo a Ajax. Tanto no lado do controlador quanto no lado da View (através de taglibs). Nativamente ele prove um result type chamado “xlst” que é responsável por serializar todos os atributos outjected no formato XML no OutputStream. Além disso, existe um plugin chamado JSON que prove um result type chamado “json” onde os atributos outjected são serializados nesse formato. Usando esse tipo de formato, torna-se muito prático o uso de chamadas remotas via javascript, que consome JSON nativamente.
Plugins: A estrutura de plugins do Struts 2 é bem robusta e prática, para ativar um plugin basta colocar o respectivo .jar na pasta lib do projeto Web. Existem diversos plugins já implementados (pela comunidade) e que servem para propósitos variados.
De forma geral, o Struts 2 parece bem produtivo, principalmente se formos comparar com a versão 1 do Struts. Agora vamos começar o estudo do JSF e tentar bolar um comparativo de produtividade. Espero que tenhamos sucesso na escolha!