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