Struts. Características Avançadas



Documentos relacionados
Minicurso de MVC web com Struts. Felipe F Nascimento felipenasc@inf.puc-rio.br

J550. Apache Struts. Helder da Rocha

Curso de Introdução ao

Prof. Roberto Desenvolvimento Web Avançado

Java para WEB. Servlets

Arquitetura de Aplicações JSP/Web. Padrão Arquitetural MVC

Material de apoio a aulas de Desenvolvimento Web. Tutorial Java WEB JSP & HTML & CSS & CLASSE & OBJETOS. AAS -

J2EE. Exemplo completo Utilização Servlet. Instrutor HEngholmJr

Tencologia em Análise e Desenvolvimento de Sistemas Disciplina: WEB I Conteúdo: WEB Container Aula 04

Java II. Sérgio Luiz Ruivace Cerqueira

Desenvolvimento WEB em JAVA. Palestrante: Lourival F. de Almeida Júnior

Associação Carioca de Ensino Superior Centro Universitário Carioca

Acessando um Banco de Dados

Universidade Católica de Brasília Pró-Reitoria de Graduação Sistemas de Informação. na Prática. Por: Fernando Goulart

Aula 03 - Projeto Java Web

Programando em PHP. Conceitos Básicos

Aula 4. Objetivos. Conteúdo dinâmico na internet.

DWR DIRECTED WEB REMOTING

TUTORIAL DE INTRODUÇÃO AO CEWOLF

Java para Desenvolvimento Web

Estudo Dirigido - Parte 1

Guia para Iniciantes do WebWork

Tutorial de NetBeans IDE Acessando banco de dados com Struts Data Source

WebWork 2. João Carlos Pinheiro.

Evolução guiada por APIs. com REST para modernizar seu legado

JavaScript. JavaScript é uma linguagem de script usada em navegadores web. É uma linguagem dinâmica, estruturada e orientada em objetos.

Java na Web. Aplicações Web

JSP: JAVA SERVER PAGES

Web e Tecnologia Java: JSP/Servlets. Aula 10. Desenvolvimento em N Camadas

TUTORIAL JSP & SERVLET

Programação II Programação para a Web. Christopher Burrows

Introdução. História. Como funciona

JSP: JAVA SERVER PAGES

Use a Cabeça! FREEMAN, Eric e Elisabeth. HTML com CSS e XHTML BASHMAN, Brian / SIERRA Kathy / BATES, Bert. Servlets & JSP

mkdir /srv/www/default/html/calculadora/imagens mkdir /srv/www/default/html/calculadora/blocos

J550. Model View Controller

Programação Orientada a Objetos com PHP & MySQL Cookies e Sessões. Prof. MSc. Hugo Souza

O que fazer ao receber o Caso de Uso NOMEDAENTIDADE CRUD?

Relatório do GPES. Conhecendo o Framework Struts

INTRODUÇÃO À TECNOLOGIA SERVLETS

DOCUMENTAÇÃO DO FRAMEWORK - versão 2.0

Manual de Integração Via Gadget. Passo a passo para realizar a integração entre websites e a plataforma Virtual Target.

Lista de Revisão. 3. Analise a afirmativa a seguir como verdadeira ou falsa e justifique.

HTML / JAVASCRIPT. A versão atual é o HTML5 (seus predecessores imediatos são HTML 4.01, XHTML 1.1, etc.).

Prática Sobre Servlets e JSP

4 A Camada de Apresentação

Como já foi muito bem detalhado no Capítulo IV, o jcompany Developer Suite pode ser

0,5 pelo negrito das palavras ID, Nome, e Analisar em outro momento.


Java II. Sérgio Luiz Ruivace Cerqueira

Programação Web Aula 12 - Java Web Software

Curso de Java. Geração de Páginas WEB através de JSP. Todos os direitos reservados Klais

Introdução ao PHP. Prof. Késsia Marchi

Criação de Servlets Name Directory Build WAR JSP/Servlet frameworks Launch URL Package Class name Generate header comments

Tutorial para criação de componentes JSF Facelets Por Érico GR 07/08/2007

Objetos Implícitos. Conceito. Instanciados pelo próprio contêiner. Disponíveis em quaisquer páginas JSP.

PadrãoIX. Módulo II JAVA. Marcio de Carvalho Victorino. Servlets A,L,F,M

PÓS-GRADUAÇÃO EM MATEMÁTICA COMPUTACIONAL INFORMÁTICA INSTRUMENTAL

Tecnologias Web. Java Enterprise Edition

Criando uma agenda simples com NetBeans 6.5

Arquitetura de uma Webapp

PASSO A PASSO GOOGLE DOCS - FORMULÁRIOS GOOGLE DOCS

Manual do Usuário CFCWeb BA

Para participar de um mapa colaborativo usando o Cmap Tools

JavaScript (Funções, Eventos e Manipulação de Formulários)

Aplicações de Linguagem de Programação Orientada a Objeto

Gerenciamento de Contatos

Java na WEB Componentes Bean

Mais sobre uso de formulários Site sem Ajax

TUTORIAL DO ALUNO. Olá, bem vindo à plataforma de cursos a distância da Uniapae!!!

Desenvolvimento de aplicação web com framework JavaServer Faces e Hibernate

MANUAL DO ANIMAIL Terti Software

Programação Web. Professor: Diego Oliveira. Conteúdo 02: JSP e Servlets

Curso de Java. Geração de Páginas WEB. TodososdireitosreservadosKlais

Manual de Utilização

AULA 3 FERRAMENTAS E APLICATIVOS DE NAVEGAÇÃO, DE CORREIO ELETRÔNICO, DE GRUPOS DE DISCUSSÃO, DE BUSCA E PESQUISA (PARTE II)

Escritório Virtual Administrativo

WEBDESIGN. Professor: Paulo Marcos Trentin - paulo@paulotrentin.com.br Escola CDI de Videira

TUTORIAL SPRING SECURITY PROGRAMAÇÃO COM FRAMEWORKS Responsáveis: Ana Luíza Cruvinel, Maikon Franczak e Wendel Borges

SILVIO COSTA MOREIRA UTILIZAÇÃO DO STRUTS FRAMEWORK NO DESENVOLVIMENTO DE UM GERENCIADOR DE EVENTOS

Web Browser como o processo cliente. Servidor web com páginas estáticas Vs. Aplicações dinâmicas para a Web:

2 echo "PHP e outros.";

02 - Usando o SiteMaster - Informações importantes

( TIAGO DOS SANTOS MENDES ) PROGRAMAÇÃO DISPOSITIVOS MOVEIS ANDROID STUDIO

Conteúdo Dinâmico. Introdução. Interação Browser x Servidor Web. Interação Browser x Servidor Web

Criando um script simples

Introdução. <facelets> Templates. Configurações. Componentes. Prof. Enzo Seraphim

Parte I. Demoiselle Mail

1 Cadastre-se Mozilla Firefox. AQUI Esqueci a senha Login Senha. Esqueci a senha Login Enviar Solicitação OBS: Nome: Login:

CONSTRUÇÃO DE BLOG COM O BLOGGER

Curso de Aprendizado Industrial Desenvolvedor WEB

Manual Integra S_Line

Programação para Internet II

Passo a Passo. WebSphere Message Broker. Fluxo como WebService

GUIA BÁSICO DA SALA VIRTUAL

Está apto a utilizar o sistema, o usuário que tenha conhecimentos básicos de informática e navegação na internet.

Programação de Computadores - I. Profª Beatriz Profº Israel

INTRODUÇÃO 12. DOCUMENTAÇÃO INTRODUÇÃO INTRODUÇÃO

Transcrição:

Struts Características Avançadas

Agenda Tags do Struts DispatchAction Multiplos arquivos de configuração Command Pattern DynaActionForm Array s Validation Framework JSP2.0 Expression Language

html html:submit html:cancel html:button html:hidden html:checkbox html:messages html:errors html:file html:form html:javascript html:image/img

html html:link html:messages html:multibox html:selection/option/options/optionscollection html:radio html:reset html:rewrite html:text html:textarea

bean bean:cookie bean:header bean:parameter bean:define bean:include bean:message bean:page bean:resource bean:size

bean bean:struts bean:write

logic logic:empty logic:present logic:iterate logic:{...}

Preparação do Ambiente Crie dois projetos (SistemaDeNoticias e SistemaDeNoticiasWeb) Configure o nome do contexto web para noticia Adicione a lib struts-extras.jar. Utilize, claro, a versão mais recente Crie as páginas Menu.jsp e index.jsp

Menu.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>.: Menu :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table> <tr> <td><html:link page="/paginainicial.do">página Inicial </html:link></td> </tr> </table> </body> </html>

index.jsp <body onload="window.location='paginainicial.do';">

DispatchAction Subtipo de Action que implementa o padrão Command Ao invés de ter várias classes Action, você centraliza todas as ações num único DispatchAction e seleciona a uma ação específica através de um parâmetro (comando) na url Muito prático, economiza várias classes, pois uma mesma Action responde a várias solicitações

NoticiaAction package net.noticias.action; import java.util.*; import javax.servlet.http.*; import net.noticias.form.*; import net.noticias.persistencia.*; import org.apache.struts.action.*; import org.apache.struts.actions.*; public class NoticiaAction extends DispatchAction { public ActionForward listar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { DAONoticia daonoticia = new DAONoticia(); request.setattribute("noticias", daonoticia.consultanoticias()); return mapping.findforward("mostrarpaginadeconsulta"); } }

Invocando um método do Dispatch Essa é uma subclasse de DispatchAction Todos os métodos devem ter a seguinte lista de parâmetros: ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response O nome do método (no nosso caso listar) será invocado pela url Noticia.do?comando=listar A url completa é http://localhost:8080/noticia/noticia.do?comando=listar

Parâmetros do dispath Noticia.do Chama a ação respectiva no strutsconfig.xml, acionando a classe NoticiaAction O método listar faz carrega uma coleção de notícias na variável noticias e chama o forward MostrarPaginaDeConsulta abrindo a página ConsultarNoticias.jsp comando=listar Parâmetro http utilizado para escolher o método

NoticiaForm package net.noticias.form; import org.apache.struts.action.*; public class NoticiaForm extends ActionForm { private String id; private String texto; private String titulo; private String data; private String tipodenoticia; private String[] noticiasselecionadas; {...} }

Detalhes Crie os métodos getter e setters Temos um atributo do tipo array Array s são utilizados para recuperar valores de componentes como listas de seleção múltipla e checkboxes Essa é uma característica do html, não do Struts

DAONoticia package net.noticias.persistencia; import java.util.*; import net.noticias.form.*; public class DAONoticia { public Collection<NoticiaForm> consultanoticias() { Collection<NoticiaForm> lista = new ArrayList<NoticiaForm>(); NoticiaForm n = new NoticiaForm(); n.setid("1"); n.setdata("01-01-2001"); n.settexto("texto da notícia 1"); n.settitulo("título da notícia 1"); lista.add(n); n = new NoticiaForm(); n.setid("2"); n.setdata("01-01-2002"); n.settexto("texto da notícia 2"); n.settitulo("título da notícia 2"); lista.add(n); n = new NoticiaForm(); n.setid("3"); n.setdata("01-01-2003"); n.settexto("texto da notícia 3"); n.settitulo("título da notícia 3"); lista.add(n); return lista; }

DAONoticia public NoticiaForm consultanoticiapeloid(string id) { NoticiaForm n = new NoticiaForm(); n.setid(id); n.setdata("01-01-2001"); n.settexto("texto da notícia " + id); n.settitulo("título da notícia " + id); n.settipodenoticia("3"); return n; } }

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>sistema de Notícias</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,/WEB-INF/struts-config-form-beans.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>

Múltiplos arquivos de configuração Arquivos de configuração tendem a crescer bastante, dificultando sua visualização Nesse exemplo separamos os form-beans do resto da aplicação Para isso, adicione os arquivos de configuração no parâmetro config separados por vírgula

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> <global-forwards> <forward name="abrirpaginaprincipal" path="/paginainicial.do" /> </global-forwards> <action-mappings> <action path="/paginainicial" forward="/menu.jsp" /> <action path="/noticia" type="net.noticias.action.noticiaaction" name="noticiaform" parameter="comando"> <forward name="mostrarpaginadeedicao" path="/editarnoticia.jsp" /> <forward name="mostrarpaginadeconsulta" path="/consultarnoticias.jsp" /> </action> </action-mappings> <message-resources parameter="messageresources" /> </struts-config>

Command Pattern A ação Noticia deve ter um parâmetro O nome padrão é comando Esse parâmetro será usado para escolher o método a ser executado

Forwards globais São forwards que podem ser utilizados por todos os actions <global-forwards> <forward name="abrirpaginaprincipal" path="/paginainicial.do" /> </global-forwards>

struts-config-form-beans.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="noticiaform" type="net.noticias.form.noticiaform" /> <form-bean name="tipodenoticiaform" type="net.noticias.form.tipodenoticiaform" /> </form-beans> </struts-config>

ConsultarNoticias.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>.: Consulta Notícias :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <tr> <td colspan=4 align=center> <h2>consulta Notícias</h2> </td> </tr> <tr> <td align=center>data</td> <td>título</td> <td>texto</td> <td>editar</td>

ConsultarNoticias.jsp </tr> <logic:iterate id="noticia" name="noticias"> <tr> <td align=center><bean:write name="noticia" property="data" /></td> <td><bean:write name="noticia" property="titulo" /></td> <td><bean:write name="noticia" property="texto" /></td> <td><html:link page="/noticia.do?comando=editar" paramid="iddanoticia" paramname="noticia" paramproperty="id"> <html:image src="imagens/edit.gif" /> </html:link> </tr> </logic:iterate> <tr> <td colspan=4 align=center><html:button onclick="window.location='paginainicial.do'" property="btnvoltar" value="sair" /></td> </table> </body> </html>

html:link e html:button html:link <html:link page="/noticia.do?comando=editar" paramid="iddanoticia" paramname="noticia" paramproperty="id"> /Noticia.do?comando=editar chama a mesma action (NoticiaAction) executando dessa vez o comando editar paramid nome do parâmetro passado na url paramname nome do bean paramproperty valor da propriedade html:button <html:button onclick="window.location='paginainicial.do'" property="btnvoltar" value="sair" /> Botão com javascript para voltar à página inicial

Novo Menu.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>.: Menu :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table> <tr> <td><html:link page="/paginainicial.do">página Inicial </html:link></td> <td><html:link page="/noticia.do?comando=listar">notícia </html:link></td> </tr> </table> </body> </html>

Tela de Consulta

Comando editar Esse novo comando consulta uma notícia pelo parâmetro iddanoticia Teremos um combobox com os tipos de notícia, para montá-lo precisamos da coleção de tipos Em seguida é só chamar o forward MostrarPaginaDeEdicao

NoticiaAction public ActionForward editar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { String id = request.getparameter("iddanoticia"); DAONoticia daonoticia = new DAONoticia(); DAOTipoDeNoticia daotipo = new DAOTipoDeNoticia(); Collection<TipoDeNoticiaForm> tipos = daotipo.consultatiposdenoticia(); NoticiaForm n = daonoticia.consultanoticiapeloid(id); request.setattribute("noticia", n); request.setattribute("tipos", tipos); return mapping.findforward("mostrarpaginadeedicao"); }

EditarNoticia.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>.: Editar Notícia :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <html:form action="/noticia?comando=confirmar"> <tr> <td colspan=3 align=center> <h2>editar Notícia</h2>

EditarNoticia.jsp </td> </tr> <tr> <td align=center>id</td> <td><html:text name="noticia" property="id" /></td> </tr> <tr> <td align=center>data</td> <td><html:text name="noticia" property="data" /></td> </tr> <tr> <td align=center>título</td> <td><html:text name="noticia" property="titulo" /></td> </tr> <tr> <td align=center>texto</td> <td><html:text name="noticia" property="texto" /></td> </tr> <tr> <td colspan=3> <tr>

EditarNoticia.jsp <td align=center>tipo de notícia: <td colspan=2> <html:select name="noticia" property="tipodenoticia"> <html:optionscollection name="tipos" value="id" label="descricao" /> </html:select></td> </tr> <tr> <td colspan=3 align=center> <html:submit value="confirmar" /> <html:button onclick="action='noticia.do?comando=listar';submit()" value="sair" property="btnsair" /></td> </tr> </html:form> </table> </body> </html>

html:form/select <html:form action="/noticia?comando=confirmar"> Os dados dessa página serão enviados para o método confirmar através da NoticiaForm <html:select name="noticia" property="tipodenoticia"> <html:optionscollection name="tipos" value="id" label="descricao" /> </html:select> html:select tag para montar uma combobox, inclusive de seleção múltipla name, property nome/propriedade do bean html:optionscollection valores do combobox name nome da collection value valor de cada option (id de cada tipodenoticia) label valor que será mostrado ao usuário Se o id do bean for igual ao id da combo, essa opção virá selecionada

html:submit <html:submit value="confirmar" /> Submete o form para a ação do form <html:button onclick="action='noticia.do?comando=listar';submit()" value="sair" property="btnsair" /> Muda o valor da ação através de javascript e a submete

Tela de Edição

Confirmando a ação O método confirmar recebe os dados do formulário de edição e faz a persistência dos dados Nossos exemplos não têm bancos de dados, mas um DAO acessando o Hibernate poderia fazer isso facilmente

NoticiaAction public ActionForward confirmar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { NoticiaForm f = (NoticiaForm) form; System.out.println("Dados informados pelo usuário"); System.out.println("ID: " + f.getid()); System.out.println("Data: " + f.getdata()); System.out.println("Título: " + f.gettitulo()); System.out.println("Texto: " + f.gettexto()); System.out.println("ID do Tipo: " + f.gettipodenoticia()); return mapping.findforward("abrirpaginaprincipal"); }

Camadas de Persistência e Negócio O Struts não fornece nenhuma API para a camada de negócio Seguindo as melhores práticas, a Action deveria acessar um fachada No nosso exemplo temos acessamos um DAO diretamente O próximo passo seria acessar efetivamente o banco relacional

TipoDeNoticiaForm package net.noticias.form; import org.apache.struts.action.*; public class TipoDeNoticiaForm extends ActionForm { private String id; private String descricao; {...} }

Alternativa A classe TipoDeNoticia é bastante simples, tem apenas código e descrição Esse tipo de classe é forte candidata a se transformar em formulário dinâmico, discutido posteriormente

struts-config.xml Acrescente a ação respectiva no arquivo de configuração (siga o padrão da ação Noticia) Já é possível notar a quantidade reduzida de classes Action <action path="/tipodenoticia" name="tipodenoticiaform" type="net.noticias.action.tipodenoticiaaction" parameter="comando"> <forward name="mostrarpaginadeedicao" path="/editartipodenoticia.jsp" /> <forward name="mostrarpaginadeconsulta" path="/consultartipodenoticia.jsp" /> </action>

TipoDeNoticiaAction package net.noticias.action; import java.util.*; import javax.servlet.http.*; import net.noticias.form.*; import net.noticias.persistencia.*; import org.apache.struts.action.*; import org.apache.struts.actions.*; public class TipoDeNoticiaAction extends DispatchAction { public ActionForward editar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { String id = request.getparameter("iddotipo"); DAOTipoDeNoticia dao = new DAOTipoDeNoticia(); TipoDeNoticiaForm tipo = dao.consultatipodenoticiapeloid(id); request.setattribute("tipo", tipo); return mapping.findforward("mostrarpaginadeedicao"); }

TipoDeNoticiaAction public ActionForward listar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { DAOTipoDeNoticia d = new DAOTipoDeNoticia(); Collection<TipoDeNoticiaForm> lista = d.consultatiposdenoticia(); request.setattribute("tipos", lista); return mapping.findforward("mostrarpaginadeconsulta"); } public ActionForward confirmar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { TipoDeNoticiaForm f = (TipoDeNoticiaForm) form; System.out.println("Dados informados pelo usuário"); System.out.println("ID: " + f.getid()); System.out.println("Data: " + f.getdescricao()); return mapping.findforward("abrirpaginaprincipal"); } }

DAOTipoDeNoticia package net.noticias.persistencia; import java.util.*; import net.noticias.form.*; public class DAOTipoDeNoticia { public Collection<TipoDeNoticiaForm> consultatiposdenoticia() { Collection<TipoDeNoticiaForm> lista = new ArrayList<TipoDeNoticiaForm>(); TipoDeNoticiaForm n = new TipoDeNoticiaForm(); n.setid("1"); n.setdescricao("tipo 1"); lista.add(n); n = new TipoDeNoticiaForm(); n.setid("2"); n.setdescricao("tipo 2"); lista.add(n); n = new TipoDeNoticiaForm(); n.setid("3"); n.setdescricao("tipo 3"); lista.add(n); return lista; } public TipoDeNoticiaForm consultatipodenoticiapeloid(string id) { TipoDeNoticiaForm tipo = new TipoDeNoticiaForm(); tipo.setid(id); tipo.setdescricao("tipo " + id); return tipo; } }

TipoDeNoticia Apesar de simples, temos vários elementos utilizados em

ConsultarTipoDeNoticia.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>.: Consulta Tipos de Notícia :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <tr> <td colspan=4 align=center> <h2>consulta Tipo de Notícia</h2> </td> </tr> <tr> <td align=center>id</td> <td>descrição</td> <td>editar</td> </tr>

ConsultarTipoDeNoticia.jsp <logic:iterate id="tipo" name="tipos"> <tr> <td align=center><bean:write name="tipo" property="id" /></td> <td><bean:write name="tipo" property="descricao" /></td> <td><html:link page="/tipodenoticia.do?comando=editar" paramid="iddotipo" paramname="tipo" paramproperty="id"> <html:img src="imagens/edit.gif" border="0" /> </html:link> </tr> </logic:iterate> <tr> <td colspan=4 align=center><html:button onclick="window.location='paginainicial.do'" property="btnvoltar" value="sair" /></td> </table> </body> </html>

Consultas As consultas seguem o mesmo princípio: a Action salva uma coleção de objetos numa variável (geralmente) de sessão e através do logic:iterate a gente escreve os vários valores na tela

EditarTipoDeNoticia.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:html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>.: Editar Tipo de Notícia :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <html:form action="/tipodenoticia?comando=confirmar" onsubmit="return validatetipodenoticiaform(this);"> <tr> <td colspan=3 align=center> <h2>edição de Tipo de Notícia</h2> </td> </tr>

EditarTipoDeNoticia.jsp <tr> <td align=center>id</td> <td><html:text name="tipo" property="id" /></td> </tr> <tr> <td align=center>descrição</td> <td><html:text name="tipo" property="descricao" /></td> </tr> <tr> <td colspan=3 align=center><html:submit value="confirmar" /><html:button onclick="action='tipodenoticia.do?comando=listar';submit()" value="sair" property="btnsair" /></td> </tr> </html:form> </table> </body> </html:html>

Edição O id de um dos objetos da lista é enviado pela url para a Action, executando o comando de edição A aplicação deve recuperar o objeto do banco e guardar seus valores em uma variável de sessão A página de edição espera essa variável e escreve seus valores através das tags html

DynaActionForm Formulário dinâmico baseado na interface java.util.map Não é necessário criar uma classe ActionForm Configurado no struts-config como um simples <form-bean> Grande flexibilidade Não utiliza reflexão

struts-config-form-beans.xml Adicione o form-bean para Fonte <form-bean name="fonteform" type="org.apache.struts.action.dynaactionform"> <form-property name="id" type="java.lang.string" /> <form-property name="descricao" type="java.lang.string" /> </form-bean> Os atributos podem usar todas as classes wrapper, collections e arrays Não é necessário criar a classe!

struts-config.xml Acrescente a Action para o novo form-bean Veja a diferença: nenhuma <action path="/fonte" type="net.noticias.action.fonteaction" name="fonteform" parameter="comando"> <forward name="mostrarpaginadeedicao" path="/editarfonte.jsp" /> <forward name="mostrarpaginadeconsulta" path="/consultarfontes.jsp"> </forward> </action>

FonteAction package net.noticias.action; import javax.servlet.http.*; import net.noticias.persistencia.*; import org.apache.struts.action.*; import org.apache.struts.actions.*; public class FonteAction extends DispatchAction { public ActionForward listar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { DAOFonte dao = new DAOFonte(); request.setattribute("fontes", dao.consultafontes()); return mapping.findforward("mostrarpaginadeconsulta"); } }

Poucas diferenças o método para listar as fontes não difere dos outros A principal diferença fica por conta do DAO, pois os formulários dinâmicos não têm classes concretas Todos são implementados através de mapas

DAOFonte package net.noticias.persistencia; import java.util.*; public class DAOFonte { public Collection<Map<String, String>> consultafontes() { Collection<Map<String, String>> lista = new ArrayList<Map<String, String>>(); Map<String, String> mapa = new HashMap<String, String>(); mapa.put("id", "1"); mapa.put("descricao", "Fonte 1"); lista.add(mapa); mapa = new HashMap<String, String>(); mapa.put("id", "2"); mapa.put("descricao", "Fonte 2"); lista.add(mapa); mapa = new HashMap<String, String>(); mapa.put("id", "3"); mapa.put("descricao", "Fonte 3"); lista.add(mapa); return lista; } public Map<String, String> consultafontepeloid(string id) { Map<String, String> mapa = new HashMap<String, String>(); mapa.put("id", id); mapa.put("descricao", "Tipo " + id); return mapa; } }

Tudo é Map Como não há classe concreta, nosso valores ficam encapsulados em mapas Para fazer a persistência num banco relacional, você deve implementar utilitários que mapeiem os mapas para seus DTO s

ConsultarFontes.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>.: Consulta Notícias :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <tr> <td colspan=4 align=center> <h2>consulta Fontes</h2> </td> </tr> <tr> <td align=center>id</td> <td>descrição</td> <td>editar</td> </tr>

ConsultarFontes.jsp <logic:iterate id="fonte" name="fontes"> <tr> <td align=center><bean:write name="fonte" property="id" /></td> <td><bean:write name="fonte" property="descricao" /></td> <td><html:link page="/fonte.do?comando=editar" paramid="iddafonte" paramname="fonte" paramproperty="id"> <html:image src="imagens/edit.gif" /> </html:link> </tr> </logic:iterate> <tr> <td colspan=4 align=center><html:button onclick="window.location='paginainicial.do';submit()" property="btnvoltar" value="sair" /></td> </tr> </table> </body> </html>

Consulta com DynaActionForm A página de consulta é idêntica a todas as outras Atenção ao DAO, pois temos que usar apenas Map s

FonteAction public ActionForward editar(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { DAOFonte dao = new DAOFonte(); String id = request.getparameter("iddafonte"); request.setattribute("fonte", dao.consultafontepeloid(id)); return mapping.findforward("mostrarpaginadeedicao"); }

EditarFonte.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>.: Editar Fonte :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <html:form action="/fonte?comando=confirmar"> <tr> <td colspan=3 align=center> <h2>editar Fonte</h2> </td> </tr>

EditarFonte.jsp <tr> <td align=center>id</td> <td><html:text name="fonte" property="id" /></td> </tr> <tr> <td align=center>descrição</td> <td><html:text name="fonte" property="descricao" /></td> </tr> <tr> <td colspan=3 align=center><html:submit value="confirmar" /> <html:button onclick="action='fonte.do?comando=listar';submit()" value="sair" property="btnsair" /></td> </tr> </html:form> </table> </body> </html>

Edição com DynaActionForm Para preencher a página de edição precisamos fornecer um mapa com os atributos da fonteform public Map<String, String> consultafontepeloid(string id) { Map<String, String> mapa = new HashMap<String, String>(); mapa.put("id", id); mapa.put("descricao", "Tipo " + id); return mapa; }

A utilização de array s Em várias situações precisamos utilizar estruturas complexas, mas quando trabalhamos com ambientes web, temos uma série de limitações Não é interessante, por exemplo, transmitir objetos entre as requisições de usuário. Esse tipo de recurso deve ser evitado ao máximo Os valores transmitidos entre as páginas são sempre do tipo String e quando temos vários componentes em uma requisição com o mesmo nome, o request encapsula seus valores em um array E trabalhar com array sempre foi razoavelmente complicado

struts-config.xml Abaixo está a Action dessa nova funcionalidade O escopo está configurado para request. Depois do primeiro teste, mude para session O parâmetro attribute= noticia cria a variável noticia e a passa para a página seguinte, preenchida com os dados da página atual <action path="/selecaomultipladenoticias" type="net.noticias.action.selecaomultipladenoticiasaction" name="noticiaform" attribute="noticia" scope="request" parameter="comando"> <forward name="mostrarpaginadeconsulta" path="/selecaomultipladenoticias.jsp" /> <forward name="mostrarnoticiasselecionadas" path="/resultadodaselecaomultipladenoticias.jsp" /> </action>

SelecaoMultiplaDeNoticiasAction package net.noticias.action; import javax.servlet.http.*; import net.noticias.persistencia.*; import org.apache.struts.action.*; import org.apache.struts.actions.*; public class SelecaoMultiplaDeNoticiasAction extends DispatchAction { public ActionForward mostrartodasasnoticias(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { DAONoticia d = new DAONoticia(); request.setattribute("noticias", d.consultanoticias()); return mapping.findforward("mostrarpaginadeconsulta"); } public ActionForward mostrarasnoticiasselecionadas(actionmapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { return mapping.findforward("mostrarnoticiasselecionadas"); } }

Página de seleção A Action simplesmente envia uma coleção de notícias para a página de seleção que mostra seus valores com uma tag html:selection

SelecaoMultiplaDeNoticias.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>.: Consulta Notícias :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <html:form action="/selecaomultipladenoticias.do?comando=mostrarasnoticiasselecionadas"> <bean:size id="quantidadedenoticias" name="noticias" /> <tr> <td colspan=2 align=center> <h2><bean:write name="quantidadedenoticias" /> Notícia(s) Cadastrada(s)</h2> </td>

SelecaoMultiplaDeNoticias.jsp </tr> <tr> <td align=center>notícias: <td><html:select name="noticia" property="noticiasselecionadas" multiple="true"> <html:optionscollection name="noticias" value="id" label="titulo" /> </html:select></td> </tr> <tr> <td colspan=2 align=center><html:button onclick="submit()" property="btnselecionar" value="selecionar" /></td> </tr> </html:form> </table> </body> </html>

html:select e bean:size <html:select name="noticia" property="noticiasselecionadas" multiple="true"> <html:optionscollection name="noticias" value="id" label="titulo" /> </html:select> multiple= true Indica que esse select aceitará seleção múltipla Os itens selecionados serão armazenados em um array do formbean <bean:size id="quantidadedenoticias" name="noticias" /> Cria a variável quantidadedenoticias com a quantidade de itens do bean noticias <bean:write name="quantidadedenoticias" /> Escreve o valor da variável quantidadedenoticias

Tela de seleção

ResultadoDaSelecaoMultiplaDeNoticias.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>.: Seleção Múltipla de Notícia :.</title> <link rel="stylesheet" href="css/estilo.css" type="text/css" /> </head> <body> <table width=90% border> <bean:size id="quantidadedenoticiasselecionadas" name="noticia" property="noticiasselecionadas" /> <tr> <td colspan=2 align=center> <h2><bean:write name="quantidadedenoticiasselecionadas" /> Notícia(s) Selecionada(s)</h2> </td>

ResultadoDaSelecaoMultiplaDeNoticias.jsp </tr> <tr> <td align=center>id</td> </tr> <logic:iterate id="iddanoticiaselecionada" property="noticiasselecionadas" name="noticia"> <tr> <td align=center><bean:write name="iddanoticiaselecionada" /></td> </tr> </logic:iterate> <tr> <td colspan=2 align=center><html:button onclick="window.location='selecaomultipladenoticias.do?comando=mostrartodasasnoticias';submit()" property="btnselecionar" value="voltar" /><html:button onclick="window.location='paginainicial.do';submit()" value="sair" property="btnsair" /></td> </tr> </table> </body> </html>

bean:size e logic:iterate <bean:size id="quantidadedenoticiasselecionadas" name="noticia" property="noticiasselecionadas" /> Cria a variável quantidadedenoticiasselecionadas com a quantidade itens da property noticiasselecionadas do bean noticia <bean:write name="quantidadedenoticiasselecionadas" /> Escreve a quantidadedenoticiasselecionadas <logic:iterate id="iddanoticiaselecionada" property="noticiasselecionadas" name="noticia"> Cria a variável iddanoticiaselecionada com o valor de cada item do array <bean:write name="iddanoticiaselecionada" /> Escreve o id na tela

Tela de resultado

Agora é sua vez O Struts entrega os dados, mas o processamento quem faz é você Seguindo as boas práticas, agora é a vez consultar as notícias pelo id, através de uma fachada/dao Nunca coloque regras de negócio em suas Actions

Validation Framework A lógica de validação é escrita em arquivos XML Originado do Validator Framework do Jakarta Incluído no Struts a partir da versão 1.1 Permite validação declarativa para vários campos Valida datas, números, email, cartão de crédito, código postar (USA), tamanhos, range e expressões regulares

Regras de Validação Regras são definidas para campos específicos de um form Já dispõe de vários validadores prontos required, minlength, maxlength, date, integer, mask Extensível: você pode criar seus próprios validadores

Validação do ActionForm Para usar o Validator, torne seus ActionForm s subclasses de ValidatorForm ou ValidatorActionForm Se estiver usando DynaActionForm, passe a extender de DynaValidatorForm ou DynaValidatorActionForm

NoticiaForm package net.noticias.form; import org.apache.struts.validator.*; public class NoticiaForm extends ValidatorActionForm { private String id; private String texto; private String titulo; private String data; private String tipodenoticia; private String[] noticiasselecionadas; {...} }

validation.xml Específico da sua aplicação Configuração das regras aplicadas a cada campo do seu formulário Torna desnecessário o método validate() do ActionForm

validator-rules.xml Fornecido pelo Struts Regras que já fazem parte do Validator Fica dentro da lib struts-core.jar, no pacote org.apache.struts.validator

Plugin Validator Para começar a usar o Validator, acrescente o plugin no struts-config.xml <plug-in classname="org.apache.struts.validator.validatorplugin"> <set-property property="pathnames" value="/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml" /> </plug-in>

Validação no Cliente O Validator pode fazer a validação no lado do cliente Para tanto, acrescente a tag seguinte logo após o <head> Essa tag irá gerar todo o código javascript para validar seu formulário <head> <html:javascript formname="noticiaform" />

Validação no Cliente É gerado automaticamente um método javascript validatexxx, onde Xxx é o nome do seu formulário Atualize a tag html:form para seus formulários <html:form action="/noticia?comando=confirmar" onsubmit="return validatenoticiaform(this)">

MessageResources # erro.tipodenoticia.id.requerido={0} é requerido erro.tipodenoticia.descricao.requerido={0} é requerida # tipodenoticia.id=id tipodenoticia.descricao=descrição # noticia.id=id noticia.data=data # errors.required={0} is required. errors.minlength={0} can not be less than {1} characters. errors.maxlength={0} can not be greater than {1} characters. errors.invalid={0} is invalid. errors.byte={0} must be a byte. errors.short={0} must be a short. errors.integer={0} must be an integer. errors.long={0} must be a long. errors.float={0} must be a float. errors.double={0} must be a double. errors.date={0} is not a date. errors.range={0} is not in the range {1} through {2}. errors.creditcard={0} is an invalid credit card number. errors.email={0} is an invalid e-mail address.

Mensagens Personalizadas O Validator já tem várias mensagens configuradas (em inglês) Você pode definir suas próprias mensagens

validation.xml <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN" "http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd"> <form-validation> <formset> <form name="tipodenoticiaform"> <field property="id" depends="required,integer"> <arg key="tipodenoticia.id" /> </field> <field property="descricao" depends="required"> <msg name="required" key="erro.tipodenoticia.descricao.requerido" /> <arg key="tipodenoticia.descricao" /> </field> </form>

validation.xml <form name="noticiaform"> <field property="id" depends="required,integer"> <arg key="noticia.id" /> </field> <field property="data" depends="required,date"> <arg key="noticia.data" /> <var> <var-name>datepattern</var-name> <var-value>dd/mm/yyyy</var-value> </var> </field> </form> </formset> </form-validation>

Regras de Validação <form name="tipodenoticiaform"> Nome do formulário definido no struts-config.xml <field property="id" depends="required,integer"> Nome da propriedade e suas dependências (definidas no validator-rules.xml) <arg key="tipodenoticia.id" /> Essa é a mensagem que substitui o parâmetro {0} no MessageResources caso o campo não tenha um valor válido <field property="descricao" depends="required"> <msg name="required" key="erro.tipodenoticia.descricao.requerido" /> Essa é a mensagem personalizada para o validador required <var-name>datepattern</var-name> <var-value>dd/mm/yyyy</var-value> Padrão para data. Veja a lista na documentação da SimpleDateFormat

Exemplo de Popup s Ao lado você pode ver alguns exemplos de mensagens No primeiro você pode ver uma mensagem padrão (em inglês) e uma personalizada Para entender o mecanismo de troca de mensagens, veja todos os arquivos envolvidos

Exercícios Crie as regras de validação para o Formulário FonteForm

JSP2.0 EL Linguagem padrão da Sun para a camada de apresentação Acesso conciso, rápido e prático Acessa subpropriedades dos beans Sintaxe incrivelmente simples É da Sun...

Concorrentes jsp:usebean e jsp:getproperty Não pode acessar subpropriedades do bean Complexo e nem um pouco prático bean:write Também não pode acessar subpropriedades do bean Não é a saída mais prática Elementos de script JSP Resulta em um código JSP impossível de manter Destrói o principal propósito do MVC

Instalação da EL Para instalar você só precisa alterar o cabeçalho do web.xml Já faz parte dos containers mais novos, como Tomcat 5 Parte integrante do JSP2.0

web.xml <?xml version="1.0" encoding="iso-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd" version="2.4"> {...} </web-app>

Invocando a EL Forma básica ${expressão} ${bean.propriedade} Você pode combiná-la com as demais notações <jsp:include page="${expr1}blah${expr2}" />

Exemplo com Struts <%@ taglib uri="/web-inf/struts-bean.tld" prefix="bean" %> <UL> <LI>First name: <bean:write name="contactformbean" property="firstname"/> <LI>Last name: <bean:write name="contactformbean" property="lastname"/> <LI>Email address: <bean:write name="contactformbean" property="email"/> <LI>Fax number: <bean:write name="contactformbean" property="faxnumber"/> </UL>

Agora com EL <UL> <LI>First name: ${contactformbean.firstname} <LI>Last name: ${contactformbean.lastname} <LI>Email address: ${contactformbean.email} <LI>Fax number: ${contactformbean.faxnumber} </UL>

Exercícios No formulário de consulta notícias, combine as tags Struts com a JSP EL