Material sobre GWT Algumas Notícias
nov 04

É comum para alguém que esteja começando a programar com o GWT ter um pouco de dificuldade com a comunicação entre cliente e servidor através do mecanismo padrão do GWT, o RPC. Após receber alguns emails sobre como fazer isso resolvi escrever este post mostrando de uma forma simplificada e rápida os passos necessários para a execução dessa tarefa simples e extremamente comum em aplicações ajax.

Para começar é interessante saber como funciona esse mecanismo. De forma resumida o que acontece é o seguinte: Ao receber o seu objeto java, o compilador gwt vai transformá-lo em uma String então o serializa e em seguida envia ao servidor por meio de uma conexão HTTP normal. Ao receber esse objeto serializado o servidor(Servlet gwt) então deserializa o objeto executando o caminho inverso, transformando a String em um objeto java e então este segue o seu ciclo de vida normal. Da mesma maneira, o inverso também é verdade. Assim, a comunicação pode ser efetuada em ambos os sentidos. Para conseguir executar toda essa tarefa é necessário que o objeto a ser enviado obedeça a algumas regras, a seguir:

  1. Ser de um tipo básico/primitivo (String, Integer/int, Double/double, Long/long, Boolean/boolean ).
  2. Implementar a interface Serializable ou IsSerializable(gwt < 1.4).
  3. Todos os campos do objeto devem obedecer à(s) regra(s) 1 e/ou 2.

O uso de coleções e mapas é permitido desde que se use generics e os tipos que elas encapsulem obedeçam às regras citadas anteriormente. Assim é possível se ter por exemplo uma List<String> trafegando entre o cliente e o servidor.

Abaixo você encontra o diagrama de implementação de um serviço rpc do gwt.

Diagrama de Implementação de um Serviço RPC

Diagrama de Implementação de um Serviço RPC

O que essa coisa toda realmente significa é bastante simples:

  • 2 interfaces
  • 1 servlet

As duas interfaces servem para a definir o que o serviço irá realizar, por exemplo: Verificar se um usuário possui acesso a um determinado recurso, efetuar login no sistema... etc. Uma dessas interfaces é chamada de síncrona e a outra de assíncrona. O servlet define o como esse serviço será implementado e por isso ele deve implementar a interface síncrona do serviço.

Utilizando a versão 1.5 do gwt temos o seguinte:

Interface Síncrona:

JAVA:
  1. package br.com.gwt.rpc.client.servico;
  2.  
  3. @RemoteServiceRelativePath("/servico")
  4. public interface Servico extends Service{
  5.       public Boolean autoriza(String loginToken, String recurso);   
  6.       public String login(String login, String senha) throws Exception;
  7.       public void logout(String loginToken);
  8. }

Interface Assíncrona:

JAVA:
  1. package br.com.gwt.rpc.client.servico;
  2.  
  3. public interface ServicoAsync {
  4.     public void autoriza(String loginToken, String recurso, AsyncCallback&gt;Boolean&lt;callback);
  5.     public void login(String login, String senha, AsyncCallback&gt;String&lt;callback);
  6.     public void logout(String loginToken, AsyncCallback&gt;Void&lt;callback);
  7. }

Reparem que na interface Assíncrona os métodos não retornam objetos e os parâmetros dos métodos são os mesmos da interface síncrona com o acréscimo de um AsyncCallback. Entrarei em detalhes logo abaixo.

Agora, restam somente dois passos para a criação do serviço. Implementar o servlet e registrá-lo no arquivo do módulo.

JAVA:
  1. package br.com.gwt.rpc.server.servico;
  2. public class ServicoImpl extends RemoteServiceServlet implements Servico {
  3.       public Boolean autoriza(String loginToken, String recurso) {
  4.             ...
  5.             /*implementação da autorização;*/
  6.             ...
  7.       }   
  8.       public String login(String login, String senha) throws Exception {
  9.             ...
  10.             /*implementação do login*/
  11.             ...
  12.       }
  13.       public void logout(String loginToken) {
  14.             ...
  15.             /*implementação do logout*/
  16.             ...
  17.       }
  18. }

Abaixo o arquivo de configuração do módulo gwt.

XML:
  1. <module>
  2.         ...
  3.     <servlet path="/servico" class="br.com.gwt.rpc.client.servico.ServicoImpl"/>
  4.         ...
  5. </module>

A partir daí o serviço está pronto para ser usado. Repare que o path no módulo de configuração é o mesmo definido logo no início da interface síncrona. Feito isso enquanto estiver utilizando em hosted mode, não é necessário nenhuma outra configuração adicional. Para a utilização em web mode é necessária uma última configuração. Registrar o servlet no web.xml. Esta última tarefa não será coberta neste post por se tratar de uma atividade comum em uma aplicação JEE.

Para fazer uma chamada ao serviço o compilador do gwt deve ser invocado através da seguinte chamada:

JAVA:
  1. ServicoAsync servico = GWT.create(Servico.class);

As chamadas são sempre assíncronas, isso significa que é criada uma conexão HTTP com o servidor, essa chamada é executada e em algum momento ela irá retornar e então executará o código que faz parte do AsyncCallback que criamos. A seguir um exemplo de chamada ao método de login:

JAVA:
  1. ...
  2.    servico.login("login", "1234", new AsyncCallback<string> callback{
  3.      public void onSuccess(String result) {
  4.            loginToken = result;
  5.            Window.alert("Login efetuado com sucesso!");
  6.      }
  7.      
  8.      public void onFailure(Throwable cause){
  9.            Window.alert("Ocorreu uma falha no processo de login. Causa: \n"+cause.getMessage());
  10.      }
  11.    });

Abraços e até o próximo post :)

Deixe uma resposta