Struts
Aplicação de exemplo
[email protected]
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
UsuarioForm
package 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:write
name="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" />
LoginAction
package 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 strutsconfig)
• 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
DAOUsuario
package 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
LogoutAction
package 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:image
src="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
PessoaForm
package 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
PessoaAction
package 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
Download

Struts - Marco Reis