810 likes | 1.01k Views
Jakarta Struts Marco Antonio, Arquiteto de Software – TJDF ma@marcoreis.net Última revisão: Maio/2007. Struts. Struts. Framework para facilitar a implementação da arquitetura MVC em aplicações JSP. Tem se tornado um padrão mundial. Bastante completo.
E N D
Jakarta Struts Marco Antonio, Arquiteto de Software – TJDF ma@marcoreis.net Última revisão: Maio/2007 Struts
Struts • Framework para facilitar a implementação da arquitetura MVC em aplicações JSP. • Tem se tornado um padrão mundial. • Bastante completo. • Demanda muito tempo para o aprendizado.
Serviços oferecidos pelo Struts • Um poderoso Servlet de controle que faz a delegação das regras de negócio para uma classe específica. É configurado via XML. • Validadores para diversas situações. • Gerenciamento de exceção. • Utilitários para upload. • Utilitários para manipulação de javaBeans. * vários desses utilitários foram transferidos para projetos separados para reutilização em outros sistemas, mesmo sem o Struts.
Download • Faça o download do Struts no site jakarta.apache.org/struts/index.html. • Descompacte o conteúdo do Struts na sua pasta pessoal.
Principais arquivos • O framework está no arquivo struts.jar, mas, assim como tudo no Java, ele necessita de diversas outras bibliotecas. • Esse mecanismo é bastante prático, pois facilita a instalação, portabilidade, atualização, correção, etc. • Copie as bibliotecas (.jar) para o SistemaBancario/lib e registre-as (Add to Build Path). • Copie as tag libs (.tld) para o SistemaBancarioWeb/WEB-INF.
web.xml <?xml version="1.0" ?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
web.xml <taglib> <taglib-uri>/tags/struts-bean</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-logic</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-html</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> </web-app>
web.xml • Arquivo padrão para configurar qualquer aplicação web. • Deve ficar dentro do diretório WEB-INF da aplicação. • Esse diretório, a partir de agora, é obrigatório. Dentro dele estarão todas as bibliotecas necessárias ao nosso trabalho.
Principais tags do web.xml • Servlet: indica o nome do Servlet do Struts, a classe desse Servlet e o arquivo de configuração do Struts, quem vamos ver na sequência. • Load-on-startup: opcional. Faz o ActionServlet ser carregado quando o servidor web é iniciado. • Servlet-mapping: indica que o Servlet responde apenas ao padrão *.do. • Atenção: se você acessar uma página .html comum do servidor, o ActionServlet não é acessado.
web.xml • Taglib: biblioteca de tags proprietárias do Struts para fazer tarefas comuns. • Exemplos: Ler os valores dos atributos de uma classe (JavaBean), ler o arquivo de mensagens (application.properties), fazer loops, comparações, verificar condições (existe, não existe), mostrar componentes HTML. • Existem vários concorrentes, mas todos seguem o mesmo princípio, mudando apenas a sintaxe. Algumas vezes, nem isso.
Atualizando o contexto • Quando você cria um projeto no Tomcat através do plugin, é criada uma entrada similar a essa no arquivo c:\Tomcat\conf\server.xml: <Context path="/sistemabancarioweb" reloadable="true" docBase="E:\sistemas\SistemaBancarioWeb" workDir="E:\sistemas\SistemaBancarioWeb\work" > <Logger className="org.apache.catalina.logger.SystemOutLogger" verbosity="4" timestamp="true"/> </Context> • Esse arquivo tem a configuração de todas as aplicações (contextos) que existem nessa instalação do Tomcat. • Como estamos alterando bastante as configurações do ambiente, se ocorrer algum erro ou comportamento estranho da aplicação é necessário atualizar o contexto. Siga esses passos: • Botão direito no projeto (SitemaBancarioWeb) – Tomcat Project – Update Context Definition.
tools.jar • Em algumas instalações do Java temos problemas com o registro da máquina. Para evitar essa situação, vamos registrar o arquivo tools.jar, que é a biblioteca de utilitários da linguagem. • Vá no menu Window – Preferences – Tomcat e veja a configuração final no próximo slide.
Principais taglibs • Bean: gerencia os beans (classes de entidade), acessa propriedades, mensagens, cookies, etc. • Logic: faz comparações, avalia condições, faz loops, • Html: representa os componentes html, tornando a sua utilização mais simples.
struts-config.xml <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"> <struts-config> <action-mappings> <action path="/BemVindo" type="com.sistemabancario.apresentacao.action.BemVindoAction"> <forward name="Sucesso" path="/jsp/BemVindo.jsp" /> </action> </action-mappings> <message-resources parameter="resources.application" /> </struts-config>
Entenda o struts-config.xml • Path: indica a URL que deve ser chamada para executar essa ação (BemVindo). • Type: Classe que representa a ação desejada. • Forward: indica os caminho que podem ser seguidos para essa ação. Em geral, indica sucesso o fracasso para abrir alguma página. • Path (forward): página JSP que vai ser mostrada. • Message-resources: arquivo que contém as mensagens/rótulos da sua aplicação (internacionalização). Resources indica o diretório, application o arquivo. A extensão .properties fica implícita!
application.properties # cadastro.nome=Nome cadastro.endereco=Endereço cadastro.telefone=Telefone cadastro.id=Código # mensagem.editar=Editar mensagem.excluir=Excluir # cadastroDeAgencia.tituloDaPaginaDeConsulta=ConsultaAgências cadastroDeAgencia.tituloDaPaginaDeCadastro=CadastrodeAgências # cadastroDeGerente.tituloDaPaginaDeConsulta=ConsultaGerentes cadastroDeGerente.tituloDaPaginaDeCadastro=CadastrodeGerente cadastroDeGerente.listaDeGerentes=ListadeGerentes # sistema.tituloDoSistema=SistemaBancário sistema.mensagemDeBoasVindas=Bem-VindoaoSistemaBancário
application.properties • Arquivo de configuração de mensagens da aplicação. • Crie esse arquivo no SistemaBancario/src/resources. • Você pode colocar as mensagem em várias línguas e utilizá-las na sua aplicação.
BemVindoAction.java package com.sistemabancario.apresentacao.action; import javax.servlet.http.*; import org.apache.struts.action.*; public class BemVindoAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return mapping.findForward("Sucesso"); } }
Atenção • Todas as páginas JSP devem estar dentro de um diretório chamado jsp (crie esse diretório), para uma melhor organização de sua aplicação.
BemVindo.jsp 1. <%@ taglib uri="/tags/struts-bean" prefix="bean"%> 2. <linkrel="stylesheet" href="css/Estilo.css" type="text/css"> <table> <tr> <td> 3. <jsp:includepage="Cabecalho.jsp"/> <html> <head> 4. <title><bean:messagekey="sistema.tituloDoSistema"/></title> </head> <body> 5. <h1><bean:messagekey="sistema.mensagemDeBoasVindas"/></title></h1> </html>
BemVindo.jsp 1. declara que a página utiliza a taglib bean, nesse caso para ler o arquivo de mensagens. 2. folha de estilos da aplicação. 3. recurso do JSP para incluir nesse ponto, outra página .jsp. Utiliza sempre o padrão taglib:função, nesse caso jsp:include. 4. lê o arquivo de configuração e recupera a mensagem do título do sistema. Também utiliza o padrão taglib:função. A tag utilizada é bean, a função message lê a mensagem associada a uma chave. 5. lê a mensagem de boas-vindas configurada.
Cabecalho.jsp Opções: <ahref="ListarGerentes.do">Gerentes</a> | Agências | Cliente | Contas-Corrente | <ahref="BemVindo.do">Página Inicial</a>
Acessando a primeira aplicação Struts • Para acessar nossa tela de boas-vindas, utilizamos a URL seguinte: http://localhost:8080/sistemabancarioweb/BemVindo.do • A extensão .do faz parte da especificação do Struts. Esse padrão foi configurado no web.xml (url-pattern). Quando você utilizar esse padrão na URL do browser, irá chamar a aplicação Struts através do ActionServlet. • Toda vez que uma solicitação com final .do é acessada pelo browser, o Servlet do Struts entra em ação.
Dinâmica da aplicação • Você acessou a action BemVindo (struts-config.xml) através da URL BemVindo.do. • O Struts direcionou a chamada para a classe BemVindoAction. Como o objetivo é apenas mostrar a página de boas-vindas, não existe nenhum processamento extra nessa classe. • Quando estivermos consultando dados, esse processamento ficará numa classe similar. • O método chamado pelo Struts é o execute(). Veja no exemplo a lista de parâmetros. • Toda ação deve ficar em uma subclasse de Action. Por exemplo ExibirClienteAction, InserirClienteAction.
Mais uma ação • Vamos acrescentar mais uma tag action na nossa aplicação. • Dessa vez, vamos listar todos os gerentes.
struts-config.xml <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"> <struts-config> <action-mappings> <action path="/BemVindo" type="com.sistemabancario.apresentacao.action.BemVindoAction"> <forward name="Sucesso" path="/jsp/BemVindo.jsp" /> </action> <action path="/ListarGerentes" type="com.sistemabancario.apresentacao.action.ListarGerentesAction"> <forward name="Sucesso" path="/jsp/ListaDosGerentes.jsp" /> </action> </action-mappings> <message-resources parameter="resources.application" /> </struts-config>
struts-config.xml • Adicionamos a ação ListarGerentes. Para acessar essa ação acesse a URL: http://localhost:8080/sistemabancarioweb/ListarGerentes.do • Depois de acessar essa URL, o Struts irá direcionar a ação para o execute da classe ListarGerentesAction. • A maior parte de sua aplicação (na verdade, de qualquer aplicação) seguirá passos similares.
ListarGerentesAction.java package com.sistemabancario.apresentacao.action; import java.util.*; import javax.servlet.http.*; import org.apache.struts.action.*; import com.sistemabancario.persistencia.*; public class ListarGerentesAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { DAOGerente daoGerente = new DAOGerente(); Collection lista = daoGerente.consultarTodos(); request.setAttribute("gerentes", lista); return mapping.findForward("Sucesso"); } }
DAOGerente – mock package com.sistemabancario.persistencia; import java.util.*; import com.sistemabancario.formularios.*; public class DAOGerente { public FormularioGerente consultarPeloId(long id) { FormularioGerente g = new FormularioGerente(); g.setEndereco("Algum endereço"); g.setId(id); g.setNome("Algum nome"); g.setTelefone("3214-4323"); return g; } public void inserir(FormularioGerente gerente) { System.out.println("Estou inserindo um novo gerente..."); System.out.println(gerente.getId()); System.out.println(gerente.getNome()); System.out.println(gerente.getEndereco()); System.out.println(gerente.getTelefone()); } public void atualizar(FormularioGerente gerente) { System.out.println("Estou atualizando um gerente..."); System.out.println(gerente.getId()); System.out.println(gerente.getNome()); System.out.println(gerente.getEndereco()); System.out.println(gerente.getTelefone()); }
DAOGerente – mock public Collection consultaTodos() { Collection lista = new ArrayList(); FormularioGerente g = new FormularioGerente(); g.setEndereco("Taguatinga"); g.setNome("Jose"); g.setTelefone("3352-1212"); g.setId(1); lista.add(g); g = new FormularioGerente(); g.setEndereco("Asa Sul"); g.setNome("Maria"); g.setTelefone("3423-4512"); g.setId(2); lista.add(g); g = new FormularioGerente(); g.setEndereco("Asa Norte"); g.setNome("Joao"); g.setTelefone("3242-4321"); g.setId(3); lista.add(g); g = new FormularioGerente(); g.setEndereco("Lago Norte"); g.setNome("Paulo"); g.setTelefone("3248-7654"); g.setId(4); lista.add(g); return lista; } }
ListarGerentesAction • Quando você acessou a URL ListarGerentes.do, o Struts chamou o método execute (atenção para a lista de parâmetros!!!). • O objetivo é recuperar uma collection (o Struts trabalha com os tipos mais comuns do Java), que é a lista dos gerentes. Para isso utilizamos o DAOGerente. • Logo em seguida, guardamos essa lista na sessão do browser. Vamos recuperá-la posteriormente na página JSP.
ListaDosGerentes.jsp <%@ taglib uri="/tags/struts-html" prefix="html"%> <%@ taglib uri="/tags/struts-bean" prefix="bean"%> <%@ taglib uri="/tags/struts-logic" prefix="logic"%> <linkrel="stylesheet" href="css/Estilo.css" type="text/css"> <html> <head> <title><bean:messagekey="cadastroDeGerente.tituloDaPaginaDeConsulta"/> </title> </head> <body> <table> <tr> <td> <jsp:includepage="Cabecalho.jsp"/> </td> </tr> </table>
ListaDosGerentes.jsp • Declaração das taglibs que vamos usar nessa página. • Html para os componentes html. • Bean para acessar os javabeans • Logic para o loop. Lembre-se: vamos mostar vários registros.
ListaDosGerentes.jsp <h1><bean:messagekey="cadastroDeGerente.tituloDaPaginaDeConsulta"/></h1> 1. <!-- logic:presentname="gerentes" (isso é opcional)--> <tableborder="1"> <tr> <th> 2. <bean:messagekey="cadastro.nome"/> </th> <th> <bean:messagekey="cadastro.endereco" /> </th> <th> <bean:messagekey="cadastro.telefone" /> </th> <th> <bean:messagekey="mensagem.editar" /> </th> <th> <bean:messagekey="mensagem.excluir" /> </th> </tr>
ListaDosGerentes.jsp 1. utiliza a taglib logic para verificar se o atributo “gerentes” existe mesmo na sessão. Caso exista, ele executa o conteúdo, podendo mostrar uma mensagem caso não encontre o atributo na sessão. 2. lê as mensagens associadas às chaves.
ListaDosGerentes.jsp 1. <logic:iterateid="gerente" name="gerentes"> <tr> <td> 2. <bean:writename="gerente" property="nome"/> </td> <td> 3. <bean:writename="gerente" property="endereco"/> </td> <td> 4. <bean:writename="gerente" property="telefone"/> </td> <tdalign=center> 5. <html:linkpage="/ExibirGerente.do" paramId="id" paramName="gerente" paramProperty="id"> 6. <html:imagesrc="imagens/edit.gif" alt="EditarRegistro" /> </html:link> </td>
ListaDosGerentes.jsp 1. logic:iterate é uma tag que faz iteração, ou seja, repetição. Name indica o bean que limita essas repetições (gerentes, que é a lista de todos os gerentes, veja a classe ListarGerenteAction). O id representará cada um dos elementos da lista. Cada elemento será referenciado por gerente. 2. bean:write escreve na tela o valor da propriedade nome no primeiro gerente da lista. Name indica o bean gerente dessa iteração. Property indica a propriedade do bean. A propriedade deve existir no bean em questão. Todas as conversões são automáticas, por conta do Struts.
ListaDosGerentes.jsp 3. escreve o valor da propriedade endereco. 4. escreve o valor da propriedade telefone. 5. html:link é uma ligação com a action ExibirGerente. Quando você clicar aqui, vamos criar um parâmetro id com o valor do id do gerente em da iteração atual. Vamos passar esse valor para uma página e mostrar os dados desse gerente, com a finalidade de edição. Veja a imagem. 6. html:image mostra uma imagem, para fins estéticos, apenas isso.
Dinâmica da consulta • Quando acessarmos a action ExibirGerente, passaremos o id que vamos consultar. • Quando o id tiver algum valor válido, vamos carregar a tela com os dados do gerente. • Se você não passar nenhum id, o sistema irá inserir o gerente. Na outra situação, vamos atualizar um já existente.
ListaDosGerentes.jsp <tdalign=center> 1. <html:linkpage="/ExcluirGerente.do" paramId="id" paramName="gerente" paramProperty="id"> 2. <html:imagesrc="imagens/delete_2x.gif" alt="ExcluirRegistro" /> </html:link> </td> </tr> 3. </logic:iterate> <tr> <tdcolspan="5"> 4. <html:linkpage="/ExibirGerente.do"> 5. <html:imgsrc="imagens/add.gif" alt="AdicionarRegistro" border="0" align="right" /> </html:link> </table> 6. <!-- /logic:present (isso é opcional) --> </body> </html>
ListaDosGerentes.jsp 1. a exclusão funciona da mesma forma que a edição. Vamos passar um id, e a página seguinte irá excluir o gerente associado. 2. uma imagem, também para fins estéticos. 3. fim da iteração. Tudo que está entre o início e o fim da tag logic:iterate será repetido enquando existirem mais gerentes na lista. 4. abre a página de cadastro, exibindo uma página em branco, pois não foi informado nenhum id. 5. mais uma vez nossa imagem. 6. fim da tag logic:present, que verifica se realmene existe o atributos gerentes na sessão. Tem como finalidade garantir que você passou a lista dos gerentes.
struts-config.xml <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"> <struts-config> <form-beans> <form-bean name="formularioGerente" type="com.sistemabancario.apresentacao.formulario.FormularioGerente"> </form-bean> </form-beans> <action-mappings> <action path="/BemVindo" type="com.sistemabancario.apresentacao.action.BemVindoAction"> <forward name="Sucesso" path="/jsp/BemVindo.jsp" /> </action> <action path="/ListarGerentes" type="com.sistemabancario.apresentacao.action.ListarGerentesAction"> <forward name="Sucesso" path="/jsp/ListaDosGerentes.jsp" /> </action> <action path="/ExibirGerente" type="com.sistemabancario.apresentacao.action.ExibirGerenteAction"> <forward name="ExibirGerente" path="/jsp/CadastroDeGerente.jsp" /> </action>
struts-config.xml <action path="/CadastrarGerente" type="com.sistemabancario.apresentacao.action.CadastrarGerenteAction" name="formularioGerente"> <forward name="ListarGerentes" path="/ListarGerentes.do" /> </action> </action-mappings> <message-resources parameter="resources.application" /> </struts-config>
Novidades no struts-config.xml • Até agora vimos apenas ações de consulta (BemVindo e ListarGerentes). • A outra situação é o cadastro. Toda vez que precisamos de uma página para cadastro, vamos criar um formulário (form-bean) e sua respectiva classe (ActionForm).
FormularioGerente.java package com.sistemabancario.apresentacao.formulario; import org.apache.struts.action.*; public class FormularioGerente extends ActionForm { private long id; private String nome; private String endereco; private String telefone; public String getEndereco() { return endereco; } public void setEndereco(String endereco) { this.endereco = endereco; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getNome() { return nome; }
FormularioGerente.java public void setNome(String nome) { this.nome = nome; } public String getTelefone() { return telefone; } public void setTelefone(String telefone) { this.telefone = telefone; } }
FormularioGerente.java • Essa classe deve ter atributos correspondentes a todos os campos da tela. • A primeira impressão que temos é que duplicamos código, pois temos uma classe de entidade bastante parecida. • Precisamos lembrar que esse é um exemplo básico e existem estratégias específicas para eliminar esse tipo de problema.