Struts 2 + AJAX + JPA + Spring – Parte III
Struts 2 + AJAX
Para entender como funciona a integração do AJAX no Struts 2, primeiramente precisamos entender das tags do struts, na versão antiga as tags estavam divididas em três taglibs, no Struts 2, temos apenas que importar.
<%@taglib prefix=”s” uri=”/struts-tags”%>
Importando essa taglib temos acesso as todos os tipos de tags do Struts 2. Usamos o 's' como prefixo por convenção, é aconselhável mantê-lo.
Como visto na listagem 3, criamos uma tabela onde colocamos o cabeçalho da nossa listagem com alguns estilos, e na outra linha já utilizamos a tag <s:iterator/> do Struts 2 para navegarmos na nossa lista.
Passamos para o parâmetro value o nome da propriedade que é uma lista e apenas acessamos o valor de cada atributo utilizando a tag <s:property/> do struts passando o nome do atributo para o parâmetro value desta tag.
Assim já criamos nosso laço da lista de contatos. Uma tag interessante do Struts 2 é a tag <s:url/> onde criamos um link para uma action, passando para o parâmetro action o caminho para nossa action que nesse caso é /removerContato!removeUmContato.action e também passamos um parâmetro utilizando a tag <s:param/> que mapeamos o atributo id do objeto pessoa configurando o parâmetro value para pessoa.id.
Pronto, criamos nosso link para a action que ira remover este nosso registro passando como parametro o identificador do pessoa, simples não?
A tag <s:a/> também é outra tag importante do Struts 2, com ela criamos um link para nossa url utilizando ajax, configurando sua mensagem de erro, e mensagem de espera para nosso link como veremos agora explicando também a integração do AJAX com o Struts.
Antes de mais nada, se quiser utilizar ajax em suas páginas utilizando o Struts 2 deve-se utilizar a tag <s:head theme=”ajax”/>, que informa ao struts para que a página possa utilizar o tema ajax, o Struts 2 utiliza o conceito de temas para renderizar uma página, existem outros tipos, mas não abordaremos neste artigo, sugiro os links no final do artigo para que possam obter mais informações.
É interessante não se esquecer de usar a tag <s:head/> configurando o tema para ajax, pois, pode ocorrer erros se isso não for feito.
No nosso exemplo iremos utilizar um tabbedPannel que é utilizado para criar abas na nossa página utilizando ajax.
Isto é apenas uma das várias funcionalidades para o desenvolvimento da camada de visão que o Struts 2 nos fornece a partir de suas tags. Procurem mais informações nos links que vocês poderão ver que este o Struts 2 realmente facilita a vida do desenvolvedor web.
Para criarmos nosso exemplo basta configurar a tag <s:tabbedPannel/> com o parâmetro id para informar que este pannel pode ser identificado pelo nome panel1, o id é utilizado pela ongl* para que um div remoto, por exemplo, consiga identificar este tabbedPannel, no caso da página listaCOntatos.jsp nossa url é identificada pelo atributo href da tag <s:a/> utilizando o id que configuramos.
Como pode ser visto no exemplo abaixo, com atributo href criamos referencias para nossas actions ou outras tags.
<s:url id="link1" action="/removerContato!removeUmContato.action">
<s:param name="id"><s:property value="pessoa.id"/> </s:param>
</s:url>
<s:a id="linkRemove"
href="%{link1}"
theme="ajax"
notifyTopics="listaContatoTopic"
loadingText="Removendo contato.."
errorText="Ocorreu um erro durante o processamento.."
showLoadingText="true"
showErrorTransportText="true">Excluir</s:a>
Esta propriedade id é comum para todas as outras tags assim href.
A propriedade theme configurada para ajax informa que esta tag envia e recebe chamadas remotas, ou seja, estará utilizando ajax.
<s:tabbedPanel id="panel1" theme="ajax" >
O atributo theme também é comum para todas as tags, logo nosso tabbedPannel esta utilizando ajax.
Para criarmos as abas, criamos divs remotos dentro do tabbedPannel, que terá o tema configurado para ajax, e na propriedade label informamos o nome que será exibido na tela, não confunda com o nome que é dado na propriedade id, na propriedade id configuramos um nome para que o mesmo possa ser acessado dentro da página por outros divs, urls, etc.
<s:div id="listaContato"
href="listaContatos.action"
listenTopics="listaContatoTopic"
theme="ajax"
showLoadingText="true"
showErrorTransportText="true"
errorText="Um erro ocorreu, tente novamente..."
loadingText="Obtendo lista contatos...">
</s:div>
Um <s:div/> do struts possui todas as funções <div/> do html, e agrega a funcionalidade ajax, que o torna um div remoto, isso sendo possível porque utilizamos de propriedades como href=”/insereContato.action”, que cria um link com essa action, assim o resultado dessa action ira para este div.
No div listaContato esse recebera o conteúdo da página listaContato.jsp que criamos anteriormente.
No atributo listenTopics informamos qual tópico este div estará ouvindo. Como vemos no exemplo abaixo usamos a tag <s:submit/> para gravar um novo contato, e este submit esta configurado para “notificar o tópico” listaContatoTopic que o nosso div remoto listaContato esta “ouvindo” e ainda utilizar ajax para realizar a tarefa.
Podem ser configurados vários tópicos para ouvir e notificar ao mesmo tempo.
<s:form action="insereContato.action" validate="true">
<s:textfield name="contato.pessoa.nome" label="Nome"></s:textfield>
<s:textfield name="contato.pessoa.sobreNome" label="Sobrenome"></s:textfield>
<s:textfield name="contato.email" label="Email"></s:textfield>
<s:textfield name="contato.telefone.ddd" label="DDD"></s:textfield>
<s:textfield name="contato.telefone.numero" label="Numero"></s:textfield>
<s:datetimepicker name="contato.pessoa.dataDeNascimento"
label="Data de Nascimento" theme="ajax" displayFormat="dd/MM/yyyy" />
<s:submit value="Gravar" notifyTopics="listaContatoTopic"/>
</s:form>
Agora a tag <s:form/>!
É com esta tag que criamos nosso formulário, e configuraremos para utilizar ajax e validação dos campos. Não a necessidade de informar onde será exibido os erros, somente atribuir true a propriedade validate para que o form seja validado, e adivinha!?! Basta utilizar tema como ajax para que seja utilizado ajax para fazer isso, mas o Struts 2 utiliza o DWR para validações e DOJO para as outras funcionalidades ajax que estávamos utilizando ate agora.
Então se quiser validação dos campos com ajax deve configurar o servlet do DWR no arquivo web.xml, demonstrado na listagem 8 e informar que o tema de nosso form é ajax.
Utilizamos a tag <s:textfield/> para exibir o nome que ira aparecer na página jsp com o atributo label e configuramos a propriedade que ira receber com o atributo name, com a tag <s:datetimepicker/> criamos um calendário utilizando o tema ajax, configuramos também um label e um name exatamente como a tag <s:textfield/> e usamos o atributo displayFormat para configurar como será exibido a data, usamos o formato dd/MM/yyyy em nosso exemplo.
Somente isso é necessário para criar um calendário usando ajax e o mais importante, nenhuma linha de javascript.
<servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
Listagem 8 – Declaração do servlet do DWR no arquivo web.xml
Com a tag <s:submit/> tendo o parâmetro notifyTopics configurado para listaContatoTopic toda vez que um submit for realizado será notificado quem estiver ouvindo este tópico logo estas serão atualizadas.
Pronto!
Seu formulário esta sendo validado e utilizando ajax, na figura 3 pode se ver a página de login que foi criada.
Como nosso div listaContato esta ouvindo o tópico listaContatoTopic pelo atributo listenTopics este div será atualizado toda vez que for notificado.
Aqui criamos então nossa camada de visão utilizando os tabbedPannel do struts, como cada aba é um <s:div/> poderíamos criar quantos quiséssemos e apenas configurá-los para usar o tema ajax e pronto!
Figura 3 - Tela de Cadastro
Figura 4 – Listagem de contatos
Vocês podem ver que nosso cadastro esta em uma aba de nosso tabbedPannel e a listagem que possui o link para remover o registro esta em outra aba, vejam a aba da listagem de contatos na figura 4.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JavaMagazine</title>
</head>
<s:head theme="ajax" />
<body background="lightblue">
<s:tabbedPanel id="panel1" theme="ajax" >
<s:div label="Cadastro" theme="ajax">
<center>
<div>
<table border="2" cellspacing="0" cellpadding="10" bordercolor="blue"
background="buttonhighlight" align="center">
<tr>
<td><b>Formulário de Registro</b></td>
</tr>
<tr>
<td>
<s:form action="insereContato.action" validate="true">
<s:textfield name="contato.pessoa.nome" label="Nome"></s:textfield>
<s:textfield name="contato.pessoa.sobreNome" label="Sobrenome"></s:textfield>
<s:textfield name="contato.email" label="Email"></s:textfield>
<s:textfield name="contato.telefone.ddd" label="DDD"></s:textfield>
<s:textfield name="contato.telefone.numero" label="Numero"></s:textfield>
<s:datetimepicker name="contato.pessoa.dataDeNascimento"
label="Data de Nascimento" theme="ajax" displayFormat="dd/MM/yyyy" />
<s:submit value="Gravar" notifyTopics="listaContatoTopic" ></s:submit>
</s:form></td>
</tr>
</table>
</div>
</center>
</s:div>
<s:div label="Lista Contatos" theme="ajax">
<center>
<s:div id="listaContato"
href="listaContatos.action"
listenTopics="listaContatoTopic"
theme="ajax"
showLoadingText="true"
showErrorTransportText="true"
errorText="Um erro ocorreu, tente novamente..."
loadingText="Obtendo lista contatos...">
</s:div>
<s:submit href="removerContato!removeLista.action"
value="Limpar Lista"
notifyTopics="listaContatoTopic"
theme="ajax"
align="center"
showLoadingText="true"
showErrorTransportText="true"
errorText="Um erro ocorreu, tente novamente..."
loadingText="Limpando lista contatos..."
/>
</center>
</s:div>
</s:tabbedPanel>
</body>
</html>
Listagem 9 – contato.jsp
A página contato.jsp completa esta na listagem 9.