Struts Aplicação de exemplo [email protected]. Aplicação de exemplo Vamos criar uma aplicação...
Transcript of Struts Aplicação de exemplo [email protected]. Aplicação de exemplo Vamos criar uma aplicação...
StrutsAplicação de exemplo
Aplicação de exemplo• Vamos criar uma aplicação para ver os
principais componentes do Struts• Não faremos acesso ao banco de dados,
mas veremos as entradas onde ele pode ser usado
• Veremos algumas das melhores técnicas para gerenciar o emaranhado de classes, arquivos de configuração e lib’s de todo projeto java
Primeiros passos• Crie a estrutura de diretórios para o projeto• Escreva o web.xml• Escreva o struts-config.xml• Escreva as classes ActionForm• Escreva as classes Action• Crie o arquivo de mensagens• Escreva as páginas JSP• Instale e teste sua aplicação
AloMundo• Vamos criar um projeto
chamado AloMundo• Crie uma pasta chamada lib e
copie nela todas as nossas bibliotecas
• registre-as: botão direito -> Build Path -> Add to Build Path
• No fim de tudo, teremos algo parecido com a imagem ao lado
AloMundo• Contém as classes de formulário, actions e
as lib’s do Struts• Nesse projeto teremos o processamento das
requisições, forwards e arquivos de mensagens*
• Representa o Model e o Controller do MVC• Não é interessante ter regras de negócio
aqui, mas esse é um assunto para outro curso
Propriedades• Botão
direito no projeto -> Properties
• Guia Libraries
• Botão Add Variable
Nova variável• Clique no botão
Extend...
Lib do Tomcat• Vamos adicionar
algumas lib’s do Tomcat• As classes do Struts
precisam dessas bibliotecas
• Precisamos adicionar o commons-el, jsp-api e servlet-api
Agora, a parte web• Vamos criar mais um projeto, dessa
vez será o AloMundoWeb• Aqui teremos as páginas web, folhas
de estilo, arquivos de configuração e taglib’s
• Representa a parte View do MVC• Copie as taglib’s para o diretório
informado na imagem ao lado• A imagem ao lado é do projeto no seu
final
web.xml• Arquivo de configuração da aplicação web• Esse arquivo segue a especificação da Sun• Não é um arquivo de configuração do Struts
propriamente dito• Declara o servlet de controle do Struts, bem
com suas taglib’s
web.xml<?xml version="1.0" encoding="iso-8859-1"?>
<!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> <display-name>Alo Mundo - Struts</display-name> <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>
web.xml <!-- Standard Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
<taglib> <taglib-uri>/tags/struts-bean</taglib-uri> <taglib-location>/WEB-INF/lib/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-html</taglib-uri> <taglib-location>/WEB-INF/lib/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/tags/struts-logic</taglib-uri> <taglib-location>/WEB-INF/lib/struts-logic.tld</taglib-location> </taglib>
</web-app>
struts-config.xml• Principal arquivo de configuração do Struts• Essa é sua primeira versão, onde iremos
apenas mostrar a página de boas-vindas da aplicação
struts-config.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts-config PUBLIC "-//Apache Software
Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config> <action-mappings> <action path="/BemVindo" forward="/BemVindo.jsp" /></action-mappings>
</struts-config>
struts-config.xml• A parte importante aqui é essa:
– <action path="/BemVindo“ forward="/BemVindo.jsp" />
• O path é o caminho referenciado pelo browser, com o sufixo “.do”
• O Struts irá abrir a página BemVindo.jsp
index.jsp<body onLoad="window.location='BemVindo.do';">
Cont.• Artifício de programação HTML para
redirecionar a aplicação para a página inicial
BemVindo.jsp<%@ page language="java" contentType="text/html; charset=UTF-8"%><%@ taglib uri="/tags/struts-html" prefix="html"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>.: Bem-Vindo :.</title><link rel="stylesheet" href="css/Estilo.css" type="text/css" /></head><body><table width=90% height=90%><tr><td align=center><table border><tr><td align=center>Esta é sua primeira aplicação Struts!<p><html:link href="TelaDeLogin.do">Tela de login</html:link><p><html:image src="imagens/ar_design.gif" /></tr></table></td></tr></table></html>
Tags• struts-html: importa as taglibs com controles
html • Exemplos:
– html:link – tag para montar um link– html:image – tag para mostrar uma imagem
Para acessar a aplicação• http://localhost:8080/alomundo• A url acima irá acessar a página index.jsp
que irá redirecionar a aplicação para BemVindo.do
• A partir desse momento o controller do Struts estará controlando a aplicação
Atenção• A imagem está no link
http://marcoreis.net/imagens/ar_design.gif • A folha de estilo também:
http://marcoreis.net/css/Estilo.css • Todos os demais arquivos seguem o mesmo
princípio
Próxima fase• Agora, vamos aumentar a complexidade da
nossa aplicação, adicionando mais alguns mapeamentos e arquivos
MessageResources.properties#login.nome=Nome:login.senha=Senha:#errors.header=<table><tr><td>Erros no formulário</td></tr>errors.login.nome=<tr><td>Nome é obrigatório</td></tr>errors.login.senha=<tr><td>Senha incorreta</td></tr>errors.footer=</table>
Mensagens• Podemos associar uma chave com uma
palavra/frase• errors.header e errors.footer fazem parte de
um padrão, representam o cabeçalho e rodapé da área de erros
UsuarioFormpackage com.alomundo;import org.apache.struts.action.*;public class UsuarioForm extends ActionForm { private String nome; private String senha; public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getSenha() { return senha; } public void setSenha(String senha) { this.senha = senha; }}
UsuarioForm• O formulário de login propriamente dito• Deve ter um atributo para campo da tela• Os valores serão preenchidos
automaticamente pelo Controller• Cada tela terá seu próprio formulário
struts-config.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts
Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"><struts-config> <form-beans> <form-bean name="usuarioForm" type="com.alomundo.UsuarioForm"></form-bean> </form-beans> <action-mappings> <action path="/BemVindo" forward="/BemVindo.jsp" /> <action path="/TelaDeLogin" forward="/TelaDeLogin.jsp" /> <action path="/EfetuarLogin" name="usuarioForm“
type="com.alomundo.LoginAction" attribute="usuario"> <forward name="Sucesso" path="/PaginaPrincipal.jsp" /> </action> </action-mappings> <message-resources parameter="MessageResources" /></struts-config>
Variáveis de sessão• <form-beans>
– Todos os formulários da sua aplicação devem estar registrados
– Dessa maneira o framework pode mapear o conteúdo dos campos de sua página para os atributos de sua classe
Nova versão do EfetuarLogin• Esse bloco de código representa uma ação típica de
uma aplicação Struts• O Struts cria uma variável de sessão do tipo
UsuarioForm chamada usuario e mapeia nela os campos da página
• Os nomes dos campos da página e do bean devem ser iguais
<action path="/EfetuarLogin" name="usuarioForm" type="com.alomundo.LoginAction" attribute="usuario">
TelaDeLogin.jsp<%@ page language="java" contentType="text/html; charset=UTF-8"%><%@ taglib uri="/tags/struts-html" prefix="html"%><%@ taglib uri="/tags/struts-bean" prefix="bean"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>.: Login :.</title><link rel="stylesheet" href="css/Estilo.css" type="text/css" /></head><body><table width=90% height=90%><tr><td align=center><table width=50% border><tr><td><table width=100%><html:form action="/EfetuarLogin"><tr><td colspan=2><html:errors />
TelaDeLogin.jsp<tr><td><bean:message key="login.nome" /></td><td><html:text property="nome" name="usuario" /></td></tr><tr><td><bean:message key="login.senha" /></td><td><html:password property="senha" name="usuario" /></td></tr><tr><td colspan=2 align=center><html:submit value="Entrar" /></td></tr><tr><td colspan=2 align=center><html:image src="imagens/cup.gif" /></td></tr></html:form></table></td></tr></table></td></tr></table></body></html>
TelaDeLogin.jsp• struts-bean: taglibs para manipulação de
beans• html:errors – mostra as mensagens de erro
que se aplicam para essa página• html:text/password – faz a ligação entre uma
caixa de texto e uma propriedade do bean (no caso, usuario)
• bean:message – recupera uma mensagem do arquivo de mensagens
PaginaPrincipal.jsp<%@ taglib uri="/tags/struts-bean" prefix="bean"%><%@ taglib uri="/tags/struts-html" prefix="html"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>.: Alô Mundo - Struts :.</title><link rel="stylesheet" href="css/Estilo.css" type="text/css" /></head><body><table width=90% height=90%><tr><td align=center><table border><tr><td align=center>Bem-Vindo ao sistema, <bean:writename="usuario" property="nome" /><p><html:link href="BemVindo.do">Página Inicial</html:link><p><html:image src="imagens/T4.gif" /></p></td></tr></table></td></tr></table></html>
Acesso a beans• Lembra que temos a variável de sessão usuario
preenchida com os valores informados na página?• Esse é o momento de acessá-la• No trecho seguinte estamos escrevendo na tela a
propriedade nome do bean usuario
<bean:write name="usuario" property="nome" />
LoginActionpackage com.alomundo;
import javax.servlet.http.*;import org.apache.struts.action.*;
public class LoginAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm
form, HttpServletRequest request, HttpServletResponse response) { UsuarioForm f = (UsuarioForm) form; System.out.println("Dados fornecidos pelo usuário:"); System.out.println("Nome:" + f.getNome()); System.out.println("Senha: " + f.getSenha()); return mapping.findForward("Sucesso"); }}
LoginAction• O Controller executa o método execute• A variável f (UsuarioForm) já foi preenchida
com os valores da tela• A classe irá direcionar a aplicação para o
mapeamento Sucesso (veja no struts-config)
• Poderíamos direcionar para outro lugar se o usuário não fosse validado
Versão final• Nossa aplicação conhecerá agora alguns
novos recursos• Atenção para os conceitos• Não é o momento de entender todos os
detalhes do Struts
DAOUsuariopackage com.alomundo;
public class DAOUsuario { public boolean validaUsuario(String nome, String
senha) { if (senha.equals("senha")) { return true; } return false; }}
DAOUsuario• Classe responsável pelo acesso a dados• Nessa nossa implementação não faz quase
nada, apenas valida o usuário com uma senha já definida
• Uma versão completa será discutida posteriormente
LoginAction public ActionForward execute(ActionMapping mapping, ActionForm
form, HttpServletRequest request, HttpServletResponse response) { UsuarioForm f = (UsuarioForm) form; DAOUsuario dao = new DAOUsuario(); if (dao.validaUsuario(f.getNome(), f.getSenha())) { return mapping.findForward("Sucesso"); } else { ActionErrors e = new ActionErrors(); e.add("senha", new ActionMessage("errors.login.senha")); saveErrors(request, e); return new ActionForward(mapping.getInput()); } }
LoginAction• Atualize o método execute• Se não conseguir validar o usuário, preenche a
variável errors com uma mensagem padrão do arquivo MessageResources
• Para voltar à mesma página mostrando a mensagem de erro utilizamos o bloco de código return new ActionForward(mapping.getInput());
UsuarioForm public ActionErrors validate(ActionMapping
mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if (nome.equals("")) { errors.add("nome", new
ActionMessage("errors.login.nome")); } return errors; }
UsuarioForm• Adicione esse método• Implementação padrão para validação• Se o usuário não informar o nome
adicionamos uma mensagem de erro do arquivo ResourceMessages
struts-config.xml<action path="/EfetuarLogin" name="usuarioForm"
type="com.alomundo.LoginAction" attribute="usuario" validate="true" input="/TelaDeLogin.jsp"> <forward name="Sucesso" path="/PaginaPrincipal.jsp" /></action>
struts-config.xml• Atualize a ação EfetuarLogin• validate=“true” diz que esse formulário
(UsuarioForm) deve passar pelo método validate() para essa ação
• O input indica a página que será aberta no caso do formulário não ser validado
Versão final• Vamos acrescentar a rotina de logout e uma
mensagem para verificar se o usuário já está autorizado
LoginAction } else { ActionErrors e = new ActionErrors(); e.add("senha", new
ActionMessage("errors.login.senha")); saveErrors(request, e); request.getSession().removeAttribute("usuario"); return new ActionForward(mapping.getInput()); }
LoginAction• Em caso de erro, precisamos remover a
variável usuario da sessão
LogoutActionpackage com.alomundo;
import javax.servlet.http.*;import org.apache.struts.action.*;
public class LogoutAction extends Action { public ActionForward execute(ActionMapping mapping,
ActionForm form, HttpServletRequest request, HttpServletResponse
response) { request.getSession().removeAttribute("usuario"); return mapping.findForward("Sucesso"); }}
LogoutAction• Quando o usuário clicar no link Sair do
sistema também removemos o bean da sessão
UsuarioForm if (nome.equals("")) { errors.add("nome", new
ActionMessage("errors.login.nome")); request.getSession().removeAttribute("usuario"); }
UsuarioForm• Mais uma vez, se houver algum erro na
validação, removemos a variável da sessão
struts-config.xml<action path="/EfetuarLogout“
type="com.alomundo.LogoutAction" validate="false"> <forward name="Sucesso" path="/BemVindo.jsp" /></action>
struts-config.xml• Quando o usuário estiver saindo do sistema
não é necessário validar o formulário• O default é true, por isso precisamos mudá-
lo para false
TelaDeLogin.jsp<%@ page language="java" contentType="text/html; charset=UTF-8"%><%@ taglib uri="/tags/struts-html" prefix="html"%><%@ taglib uri="/tags/struts-bean" prefix="bean"%><%@ taglib uri="/tags/struts-logic" prefix="logic"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>.: Login :.</title><link rel="stylesheet" href="css/Estilo.css" type="text/css" /></head><body><table width=90% height=90%><tr><td align=center><table width=50% border><tr><td colspan=2><html:errors /><tr><td><table width=100%>
TelaDeLogin.jsp<logic:present name="usuario"><tr><td>Você já está autorizado, <bean:write name="usuario"property="nome" /></td></tr><tr><td><html:link action="/EfetuarLogout">Sair do
Sistema</html:link></td></tr><tr><td><html:link action="/EfetuarLogin">Entrar no
Sistema</html:link></td></tr></logic:present>
TelaDeLogin.jsp<logic:notPresent name="usuario"><html:form action="/EfetuarLogin"><tr><td><bean:message key="login.nome" /></td><td><html:text property="nome" name="usuario" /></td></tr><tr><td><bean:message key="login.senha" /></td><td><html:password property="senha" name="usuario" /></td></tr><tr><td colspan=2 align=center><html:submit value="Entrar" /></td></tr><tr><td colspan=2 align=center><html:imagesrc="imagens/cup.gif" /></td></tr></html:form></logic:notPresent>
TelaDeLogin.jsp</table></td></tr></table></td></tr></table></body></html>
Tags lógicas• logic:present – verifica se o bean usuario
está carregado na sessão• O bloco dentro dessa tag só aparecerá se o
bean for diferente de null• Ou seja, se o usuário já tiver acessado o
sistema, mostramos apenas uma mensagem para ele e dando a opção de ir para a página inicial ou sair
Tags lógicas• logic:notPresent – esse bloco será mostrado
se o bean não estiver carregado• Nesse caso, mostramos a tela de login
Exercício• Vamos criar um cadastro de pessoas• Os atributos do ActionForm são nome,
endereço, telefone e cpf, todos do tipo String• Na página principal, vamos acrescentar um
link para esse cadastro
PessoaFormpackage com.alomundo;
import org.apache.struts.action.*;
public class PessoaForm extends ActionForm { private String nome; private String endereco; private String telefone; private String cpf;
public String getCpf() { return cpf; }
public void setCpf(String cpf) { this.cpf = cpf; }
PessoaForm public String getEndereco() { return endereco; } public void setEndereco(String endereco) { this.endereco = endereco; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getTelefone() { return telefone; } public void setTelefone(String telefone) { this.telefone = telefone; }}
Formulário• Nenhuma novidade nesse formulário, não é?
MessageResources#
pessoa.nome=Nome:
pessoa.endereco=Endereço:
pessoa.telefone=Telefone:
pessoa.cpf=CPF:
Mais mensagens• Vamos acrescentar mais essas mensagens
ao nosso arquivo ResourceMessages
CadastroDePessoa.jsp<%@ page language="java" contentType="text/html; charset=UTF-8"%><%@ taglib uri="/tags/struts-html" prefix="html"%><%@ taglib uri="/tags/struts-bean" prefix="bean"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>.: Login :.</title><link rel="stylesheet" href="css/Estilo.css" type="text/css" /></head><body><table width=90% height=90%><tr><td align=center><table width=50% border><tr><td colspan=2><html:errors /><tr><td><table width=100%>
CadastroDePessoa.jsp<html:form action="/CadastrarPessoa"><tr><td><bean:message key="pessoa.nome" /></td><td><html:text property="nome" name="pessoa" /></td></tr><tr><td><bean:message key="pessoa.endereco" /></td><td><html:text property="endereco" name="pessoa" /></td></tr><tr><td><bean:message key="pessoa.telefone" /></td><td><html:text property="telefone" name="pessoa" /></td></tr><tr><td><bean:message key="pessoa.cpf" /></td><td><html:text property="cpf" name="pessoa" /></td>
CadastroDePessoa.jsp</tr><tr><td colspan=2 align=center><html:submit value="Gravar" /></td></tr><tr><td colspan=2 align=center><html:image src="imagens/cup.gif" /></td></tr></html:form></table></td></tr></table></td></tr></table></body></html>
Nova página de cadastro• Nossas páginas são formadas por
mensagens e componentes HTML• Não se esqueça: esses componentes são
ligados (bind) aos atributos do formulário em questão
PaginaPrincipal.jsp<p><html:link href="BemVindo.do">Página Inicial</html:link><p><html:link href="CadastroDePessoa.do">Cadastro de
Pessoa</html:link><p><html:image src="imagens/T4.gif" /></p>
Menu da página principal• Vamos acrescentar a chamada ao nosso
novo cadastro• Quando o usuário clicar no link
CadastroDePessoa o Struts irá direcionar a aplicação para a página CadastroDePessoa.jsp
struts-config.xml<form-beans><form-bean name="usuarioForm"
type="com.alomundo.UsuarioForm" /><form-bean name="pessoaForm" type="com.alomundo.PessoaForm" /></form-beans>
Lista de formulários• Todos os formulários criados devem ser
registrados nessa tag
struts-config.xml<action path="/CadastroDePessoa" forward="/CadastroDePessoa.jsp" /><action path="/CadastrarPessoa" name="pessoaForm" type="com.alomundo.PessoaAction"
attribute="pessoa" scope="request"> <forward name="Sucesso" path="/PaginaPrincipal.jsp" /></action>
Ações do novo cadastro• Os dados da variável usuario ficam
gravados na sessão e podem ser usados a qualquer instante
• Os dados desse formulário não precisam viver mais que o próprio request, não precisa ficar guardado para depois
PessoaActionpackage com.alomundo;
import javax.servlet.http.*;import org.apache.struts.action.*;
public class PessoaAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { PessoaForm f = (PessoaForm) form; System.out.println("Dados recuperados da tela"); System.out.println("Nome: " + f.getNome()); System.out.println("Endereço: " + f.getEndereco()); System.out.println("Telefone: " + f.getTelefone()); System.out.println("CPF:" + f.getCpf()); return mapping.findForward("Sucesso"); }}
PessoaAction• Quando o usuário clicar no botão Gravar o
Struts chama o método execute
Agora é sua vez• Seguindo os exemplos que vimos, crie um
cadastro de notícias• Sua notícia terá titulo, texto e data, todos do
tipo String