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!

 

jpmdsajsp3fig01.jpg
Figura 3 - Tela de Cadastro

 

jpmdsajsp3fig02.jpg
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.

Leia todos os artigos da série