O Struts 2 foi inicialmente distribuído em Janeiro de 2001, obtendo um sucesso incrível entre os desenvolvedores Java. O Struts na sua versão inicial oferecia um padrão MVC (Model-View-Controller ou Modelo-Visão-Controlador) para desenvolvimento Java Web. O Struts facilitava bastante o gerenciamento, a reutilização e a manutenção do código. Com o decorrer dos anos, o desenvolvimento com Struts foi decaindo bastante, muito em função da quantidade de código exigido para que o desenvolvedor possa implementar as facilidades necessárias de um aplicativo web, portanto, uma nova proposta para uma nova versão do Struts foi sugerida.
A arquitetura do novo Struts 2 exigiu alterações bastante significativas, porém ao invés de começar do zero o novo framework Struts 2, seus desenvolvedores optaram por fazer uma fusão de outros frameworks Java de código-fonte aberto.
O grande pilar do Struts 2 foi o WebWork, um projeto da iniciativa OpenSymphony. Portanto, o WebWork se fundiu com a Apache e tornou-se a base do Struts 2. Para conhecer a história do Struts 2 visite [1] nas referências bibliográficas.
Vale ressaltar que muitas das características do WebWork e do Struts 2 são tiradas do Ruby On Reils, com o objetivo de tornar estes frameworks mais produtivos e de uso mais fácil pelos desenvolvedores.
Características
Vamos analisar algumas das características do Struts 2 que o ajudaram a se tornar um framework mais amigável e produtivo ao desenvolvedor.
- Linguagem Java: A linguagem Java tem mais de 10 anos de vida, possuindo diversas bibliotecas disponíveis que facilitam a vida dos programadores para se concentrarem mais no seus negócios e menos na infraestrutura e características da linguagem. Com uma plataforma madura por trás, o Struts está disponível para quem trabalha com Java.
- Plug-ins: O Struts 2 aceita plug-ins disponibilizados por terceiros, assim o Struts não exige que o framework venha com tudo e sim apenas as funcionalidades básicas.
- Convenções ao invés de configurações: Sempre que possível a configuração foi eliminada do Struts 2. Ao não usar configurações, nomes de classes podem oferecer mapeamento de ações, e valores de resultados retornados podem oferecer nomes para a páginas JSP serem renderizadas.
- Anotação ao invés de configuração XML: Seguindo a tendência de todos os frameworks atuais, o Struts agora disponibiliza anotações para serem utilizadas nas classes, reduzindo a configuração XML e mantendo a configuração mais perto da classe de ação.
- Conversão de dados: A conversão de valores de campos de formulários baseados em String em objetos ou tipos primitivos é tratada pela estrutura de suporte (e vice-versa), removendo a necessidade de prover este código de infraestrutura na classe da ação.
- Injeção de dependência: Seguindo mais um padrão que está sendo utilizado pela maioria dos frameworks, o Struts 2 está dando suporte para injeção de dependências, reduzindo assim o acoplamento entre as camadas do aplicativo, tornando-o muito mais simples e mais fácil de testar.
- Testabilidade: Numa época em que o TDD se torna quase uma obrigação em qualquer projeto de software de médio e grande porte, o Struts 2 facilita a vida dos desenvolvedores, tornando mais simples o teste das ações, interceptadores e outras classes do Struts 2.
Padrão MVC
O padrão MVC continua sendo usado no Struts 2, provendo uma camada de abstração entre a visualização e a estrutura de suporte por meio de uma URL.
Assim como o Struts 1, hoje o Struts 2 é bastante reconhecido entre os desenvolvedores Java Web e torna-se um poderoso competidor entre os diversos frameworks disponíveis atualmente. Struts 2 oferece produtividade e funcionalidade da Web 2.0 para os desenvolvedores.
Todas as características e a documentação completa do Struts 2 pode ser encontrada na referência [2].
Exemplo de Aplicativo Struts 2
Para criar um projeto inicial utilizando Struts 2 é muito simples. Primeiramente criamos um Dynamic Web Project utilizando a plataforma de desenvolvimento Eclipse:
Figura 1: Selecionando Other para abrir janela com mais opções
Figura 2: Selecionando a opção Dynamic Web Project
Após criado o projeto inicial, agora é necessário fazer as importações das bibliotecas do Struts 2 que serão utilizadas nos nossos projetos. Segue abaixo as bibliotecas que estamos utilizando neste projeto de exemplo.
Figura 3: Bibliotecas do Struts 2 utilizadas neste projeto
Para baixar as bibliotecas do Struts 2 basta acessar: http://struts.apache.org/download.cgi ou o link direto
Agora acesse as propriedades do projeto clicando com o botão Direito do mouse sobre o nome do projeto e selecione a opção Propriedades.
Figura 4: Acessando as propriedades do projeto
Após isso clique em Java Build Path no lado esquerdo da tela e adicione os Jars que acabamos de colar na pasta WEB-INF. Para adicioná-los basta ir em “Add Jars...” e selecionar os jars no WEB-INF.
Figura 5:Jars adicionados ao projeto
É importante colocarmos os jars no Build Path para o código “conseguir enxergar” essas bibliotecas e não acusar erros quando executarmos a aplicação.
Após esses passos, vamos construir uma aplicação simples para testar algumas funcionalidades do Struts 2. Edite o arquivo web.xml conforme abaixo:
Listagem 1: Configuração do arquivo web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Struts2Example</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Agora vamos configurar a nossa primeira classe, que é um simples Value Object, uma classe simples com setters e getters.
Listagem 2: Classe simples que será setada e adicionada para uma coleção de artigos
package br.com.struts2exemplo.action;
public class Artigo {
private Integer id;
private String titulo;
private String texto;
public Artigo(Integer id, String titulo, String texto) {
this.id = id;
this.titulo = titulo;
this.texto = texto;
}
public Artigo() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getTexto() {
return texto;
}
public void setTexto(String texto) {
this.texto = texto;
}
}
Coloque as duas classes que serão criadas no pacote br.com.struts2exemplo.action em src. Abaixo segue a nossa Action:
Listagem 3: Uma Action simples em Struts 2
package br.com.struts2exemplo.action;
import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
@Namespace(value = "/artigo")
public class ArtigoAction {
private List<Artigo> artigos;
private Artigo artigo;
public ArtigoAction() {
}
@Action(value = "lista", results = @Result(name = "ok", location = "/lista.jsp"))
public String lista() {
artigos = new ArrayList<Artigo>();
Artigo artigo1 = new Artigo(1, "Titulo 1", "Texto 1");
Artigo artigo2 = new Artigo(2, "Titulo 2", "Texto 2");
artigos.add(artigo1);
artigos.add(artigo2);
return "ok";
}
@Action(value = "novo", results = @Result(name = "ok", location =
"/artigo/adiciona.jsp"))
public String novo() {
return "ok";
}
@Action(value = "adiciona", results = @Result(name = "ok", type =
"redirectAction", params = { "actionName", "lista" }))
public String adiciona() {
return "ok";
}
public List getArtigos() {
return artigos;
}
}
Explicando de forma bastante rápida, temos no exemplo acima a anotação @Namespace(value = "/artigo") para indicar na URL em que área do sistema o usuário se encontra no momento.
A anotação @Action sobre os métodos indica que esta agora responde por requisições. Para chamar essa action basta utilizar o formato http://servidor/nomedaaplicacao/namespace/action. Se não quiser utilizar o namespace, é só retirar a anotação e retirá-lo da URL.
A anotação @Result indica para onde a action redireciona após ser executada.
Agora só falta criar a página JSP lista.jsp que será a responsável por listar os artigos.
Listagem 4: JSP responsável por listar os artigos
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Struts 2 Simples</title>
</head>
<body>
<h3>Lista de Artigos</h3>
<table>
<tr>
<td>Id</td>
<td>Titulo</td>
<td>Texto</td>
</tr>
<c:forEach items="${artigos}" var="artigo">
<tr>
<td>${artigo.id}</td>
<td>${artigo.titulo}</td>
<td>${artigo.texto}</td>
</tr>
</c:forEach>
</table>
<br>
<h5><a href="novo">Novo</a></h5>
</body>
</html>
Utilizamos apenas JSTL para percorrer a lista, aqui não há uso do Struts. Observe que ${artigos} chamará getArtigos na nossa Action. Por fim, criaremos uma simples página JSP para adicionar artigos, conforme é mostrado abaixo:
Listagem 5: JSP para adicionar artigos
<html>
<head>
<title>Exemplo Struts 2 Simples</title>
</head>
<body>
<h3>Novo Artigo</h3>
<form action="adiciona">
<table>
<tr>
<td>Titulo: <input type="text"
name="artigo.titulo"></td>
<td>Texto: <input type="text"
name="artigo.texto"></td>
<td><input type="submit"></td>
</tr>
</table>
</form>
</body>
</html>
Na nossa classe ArtigoAction poderíamos alterar o botão adicionar para salvar no Banco de dados, além disso, a lista também poderia ser alterada para recuperar informações de um Banco de dados.
Para acessar o nosso exemplo no browser, inicie o Tomcat e acesse a URL http://localhost:8080/Struts2Example/artigo/lista. A tela abaixo será exibida:
Figura 6: Exemplo da página sendo exibida no browser
Podemos notar neste simples exemplo que não usamos nenhuma configuração XML para que a aplicação possa ser executada, a não ser a configuração básica do framework Struts 2. Mas nada relativo a nossa aplicação foi necessário. Também não precisamos herdar ActionSupport e nem implementar Action como no antigo Struts 1 que acaba engessando a aplicação.
Conclusão
Neste artigo vimos algumas das novidades e principais características do Struts 2 em relação ao seu antecessor e a outros frameworks disponíveis no mercado. Por fim, fizemos uma simples aplicação de exemplo para que pudéssemos conhecer um pouco sobre este novo framework.