sexta-feira, 17 de outubro de 2014

Hello World com Struts 2 - XML

Hoje iremos desmistificar como fazer um projeto simples com struts 2, usando sua abordagem XML. É importante que a pessoa que vá seguir este tutorial já tenha certas noções de Java, Java Web, Maven e Eclipse.

Já presenciei muita gente ficando confusa quando começavam a estudar struts 2, por diversos motivos:

  • A API é diferente se comparada com a do struts 1.
  • Não existe mais struts-config.xml.
  • As taglibs mudaram.
  • Outros milhares de motivos.
Minha proposta nesse post é mostrar o quão é simples o struts 2. Primeiro, devo dar total mérito ao grande mestre Mkyong porque foi de lá que tive a idéia de fazer esse post e inclusive, aprendi lá, a fazer meu primeiro projeto struts 2. Caso você não conheça o site dele, está abaixo.

http://www.mkyong.com/

Eu uso muito o site dele pois, lá existem vários tutoriais e manuais bem escritos e que ajudam muito os desenvolvedores a resolver seus problemas. Recomendo.

Se você é do tipo de pessoa que prefere baixar logo o projeto, segue link: https://www.dropbox.com/s/oppmiq9eyi8geny/workspace_helloworldstruts2.rar?dl=0

Porém, sem mais delongas. Vamos começar.

Passo 1 - Ambiente

Precisaremos dessas ferramentas:

  • Eclipse Luna 4.4.0
  • Apache Tomcat 7.0.54 (clique aqui para baixar)
  • Maven

Precisaremos de um projeto com esta arquitetura.


Caso você não saiba como montar um ambiente assim, recomendo fortemente que você dê uma olhada nesse post: http://precisoestudarsempre.blogspot.com.br/2014/07/como-criar-um-projeto-no-eclipse-com.html

Passo 2 - Dependências

Abra seu pom.xml e ponha a seguinte dependência.

        <dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.1.2</version>
</dependency>

Passo 3 - Configuração

Abra o web.xml e ponha a configuração abaixo.

         <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>

Nesse momento, você se pergunta: "Porque eu preciso declarar esse filtro ?" Esse filtro é necessário e importante porque ele que é responsável por fazer o dispatching das requisições, ou seja, ele que redireciona a requisição HTTP para sua action correta.

Passo 4 - Mapeamento

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<package name="cliente" namespace="/Cliente" extends="struts-default">
<action name="IniciarCadastro">
<result>/WEB-INF/pages/cad-cliente.jsp</result>
</action>
<action name="Cadastrar" class="action.ClienteAction">
<result name="SUCCESS">/WEB-INF/pages/det-cliente.jsp</result>
</action>
</package>

</struts>

A única observação que faço aqui é que os atributos name e namespace são diferentes. O primeiro atributo só representa um nome a fim de, identificar o package. O segundo representa espaço de nomes da requisição, exemplo:

http://localhost:8080/HelloWorldStruts2/Cliente/Cadastrar.action

Passo 5 - Montagem da action

public class ClienteAction {
private Cliente cliente;
 
public String execute() {
cliente.setId(1L);
cliente.setNome(cliente.getNome().toUpperCase());
return "SUCCESS";
}

public Cliente getCliente() {
return cliente;
}

public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
}

Para criar uma action não é necessário estender alguma classe. Basta ter um método execute e pronto. Porém, em alguns exemplos você irá ver alguns desenvolvedores utilizando a classe ActionSupport ou a interface Action. Não se espante !! Essas classes oferecem métodos utilitários para ajudar o desenvolvedor.

Passo 6 - JSP

No nosso projeto existem duas JSPs. A primeira é um formulário de cadastro e a outra somente exibe os dados cadastrados.

Formulário de cadastro
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head></head>
<body>
<h1>Struts 2 Hello World Example</h1>

<s:form action="Cadastrar" >
<s:textfield name="cliente.nome" label="Nome" />
<s:textfield name="cliente.email" label="E-mail" />
<s:textfield name="cliente.dataNascimento" label="Data de Nascimento" />
<s:submit />
</s:form>

</body>

</html>

Reparem que o nome especificado na action é o mesmo que foi definido no struts.xml. A tag <s:textfield> cria um campo de texto, o atributo name representa o objeto que armazenará o dado e o atributo label dispensa explicação. A tag <s:submit> cria um <input type="submit">.

Exibição de dados
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head></head>
<body>
<h1>Struts 2 Hello World Example</h1>

<h4>
Dados do cliente
</h4>

Id: <s:property value="cliente.id" /><br/>
Nome: <s:property value="cliente.nome" /><br/>
E-mail: <s:property value="cliente.email" /><br/>
Data de Nascimento: <s:date name="cliente.dataNascimento" format="dd/MM/yyyy"/>

<br/>
<br/>
<a href="javascript:history.back()">Voltar</a>
</body>
</html>


A tag <s:property> exibe algo que esteja no request e a tag <s:date> é utilizada para datas. Ela oferece a opções de formatação e exibição.

Acesse: http://localhost:8080/HelloWorldStruts2/Cliente/IniciarCadastro.action

Abaixo, deixo alguns links muito bons para consulta:

Documentação do <s:date> - http://struts.apache.org/release/2.3.x/docs/date.html
Documentação da classe StrutsPrepareAndExecuteFilter - http://struts.apache.org/release/2.1.x/struts2-core/apidocs/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html
Struts 2 Hello World Example Mkyong - http://www.mkyong.com/struts2/struts-2-hello-world-example/
Download do projeto pronto: https://www.dropbox.com/s/oppmiq9eyi8geny/workspace_helloworldstruts2.rar?dl=0
Download do Tomcat: https://www.dropbox.com/s/ufln5t05aaqb59d/apache-tomcat-7.0.54.rar?dl=0

Caso eu tenha deixado algum ponto solto ou, cometi algum erro. Deixe sua contribuição nos comentários.

Nenhum comentário: