Esse artigo faz parte da revista WebMobile edição 09. Clique aqui para ler todos os artigos desta edição

Capa_WM09_M.gif

Clique aqui para ler este artigo em PDFimagem_pdf.jpgt; COLOR: teal; FONT-FAMILY: Verdana">

Construindo um WebChat com JAVA e AJAX

Leitura Obrigatória: WebMobile 5, Entendendo o AJAX.

 

...e então o AJAX explodiu... Rapidamente saiu do status de curiosidade para o de grande promessa. E a promessa logo se tornou realidade. Hoje o AJAX é um dos assuntos mais comentados nas rodas dos desenvolvedores web. Está presente nos mais diferentes tipos de sites e sistemas web. Ele também se tornou uma das bases do que se convencionou chamar de Web 2.0: uma idéia com nome pretensioso cuja proposta básica é a de que os sites se tornem tão interativos que os usuários não precisem mais instalar programas em seus computadores, mas os utilizem diretamente pela web. Uma página e componentes interativos seriam baixados de um site e seriam a interface para o usuário usar um programa cuja boa parte do código roda no servidor. O AJAX é uma das ferramentas usadas para implementar esta idéia que põe em prática um velho slogan do JAVA: "The Network is the Computer" (A rede é o computador).

Entretanto, para esse cenário se tornar realidade foi preciso simplificar o uso do AJAX e torná-lo mais "acoplável" ao código que roda no servidor. A manipulação direta do XMLHttpRequest e a necessidade de definição de documentos XML para cada requisição transformavam o uso do AJAX numa tarefa de baixa produtividade e de difícil manutenção. Mas a comunidade open-source é rápida, e logo dela surgiram diversas bibliotecas com o objetivo de facilitar o uso do AJAX em grandes sistemas. Uma das bibliotecas que revolucionaram a forma de usar o AJAX é chamada de DWR (Direct Web Remoting).

Neste artigo será apresentada a arquitetura do DWR e veremos como utilizá-la para criar aplicações de forma muito mais rápida e simples. Também será descrito em detalhes os passos necessários para a utilização do DWR em uma aplicação AJAX. Será usado um servidor web Java baseados no padrão Servlet 2.3. O artigo assume que o usuário saiba como utilizar este tipo de servidor para criação de contextos e manipulação de arquivos de configuração. Como esta implementação usa generics para diminuir o tamanho do código, você precisa da versão 1.5 da máquina virtual Java para fazer o exemplo funcionar.

DWR e objetos distribuídos

O nome dado ao DWR (Direct Web Remoting) é a primeira dica sobre sua arquitetura. Sua idéia central é a criação de um mecanismo de objetos distribuídos baseado nas tecnologias que possibilitam a existência do AJAX. Assim, quem já conhece tecnologias como CORBA e Java RMI vai se sentir bastante à vontade com os termos usados para descrever a utilização do DWR.

Como todo mecanismo de objetos distribuídos, o DWR baseia-se na geração de objetos proxy (também chamados de Stubs) no lado cliente e na operação de despachantes (dispatchers) no lado servidor. Proxy é um dos padrões de projeto clássicos (design patterns) normalmente usado em sistemas de objetos distribuídos. Neste tipo de sistema, os objetos proxy são usados para implementar referências que apontam para objetos hospedados em máquinas remotas. Um proxy implementa a interface de um objeto hospedado num servidor e consegue "esconder" do programador todo o processo de comunicação pela rede. Assim, é possível trabalhar com objetos remotos da mesma forma como se trabalha com objetos "normais". Com isso o programador não precisa mais se preocupar com a complexidade dos detalhes de comunicação e pode se concentrar nos requisitos funcionais do seu sistema.

A "mágica" que o DWR faz é justamente a criação automática de proxies em JavaScript para uso de objetos Java em um servidor de aplicações web. O DWR usa XML e o XMLHttpRequest para serializar e trafegar automaticamente os dados que correm entre os objetos Java e seus correspondentes em JavaScript. Isso tudo sem nenhuma necessidade de browsers especiais ou plug-ins específicos. Assim, temos uma forma realmente nova de construir aplicações baseadas na web. Não é preciso mais construir Servlets, Actions ou quaisquer outras classes com métodos cuja função no fim das contas é simplesmente o tratamento de requisições HTTP. O código do sistema que roda no servidor pode ser realmente independente da utilização de uma interface web.

O esquema funciona de acordo com a Figura 1. O código Java/JavaScript existente na figura é o suficiente para ver um exemplo do DWR funcionando. O objeto folhaPag no código JavaScript é o proxy criado automaticamente pelo DWR que pode ser usado para fazer chamadas a um objeto instanciado no contexto do servidor web como se o mesmo estivesse presente na memória do browser! É obvio que a natureza assíncrona do AJAX traz uma certa incompatibilidade com o modelo clássico de RPC/RMI. No caso da figura, observe que ainda é necessário o uso de funções de callback.

 

image001.gif

Figura 1. Exemplo do fluxo de informação do DWR.

 

Mas, o principal a observar é que toda aquela parte complicada que envolvia XML e o XMLHttpRequest ficam escondidas pelo DWR! Ele é responsável por serializar automaticamente os parâmetros de entrada e saída dos métodos e reagrupá-los corretamente em suas representações em Java e JavaScript. No lado cliente, este papel é executado pelos proxies gerados automaticamente pelo DWR e carregados no browser. No lado servidor, entra em cena o DWRServlet, que despacha as chamadas vindas dos proxies para os objetos correspondentes de acordo com um arquivo de configuração próprio. Com isso, o mecanismo de “RMI” se completa e o cenário da aplicação fica parecido com o da Figura 2.

                                  

image002.png

Figura 2. Arquitetura básica do DWR.

 

Além de todo esse esquema de comunicação, o DWR ainda agrega um excelente conjunto de funções em JavaScript que aumentam ainda mais a produtividade no trabalho com AJAX na hora de apresentar os dados obtidos do servidor. Assim, o desenvolvedor pode contar com ferramentas de nível muito mais alto e é capaz de criar sistemas ainda mais interativos de forma rápida e simples. Na seção a seguir, são apresentados os passos necessários para se criar uma aplicação usando DWR semelhante a um WebChat.

Criando o DWRChat

Criaremos uma aplicação para simular um WebChat com a comunicação baseada no DWR. Para isso, crie inicialmente um contexto da aplicação web num servidor Java à sua escolha. Vamos chamar o contexto da aplicação de chatdwr. Antes de começar com o DWR, teste o funcionamento do contexto para isolar os possíveis problemas futuros. Considerando que estamos usando o servidor Tomcat em sua configuração padrão, um endereço para teste do contexto seria http://127.0.0.1:8080/chatdwr/.

O primeiro passo na jornada rumo ao DWR é o download das bibliotecas. Ele pode ser encontrado no site da empresa Getahead, responsável pela distribuição do DWR (http://getahead.ltd.uk/dwr/). No site é possível encontrar as versões para download e a documentação on-line. A versão atual é a 1.1 e pode ser encontrada diretamente pela url http://getahead.ltd.uk/dwr/download. Se você não pretende dar uma olhada nos fontes, pode baixar a versão “JAR File”, pois é menor e mais simples de utilizar. Não é preciso extrair o conteúdo do arquivo, basta copiá-lo para o diretório WEB-INF\lib do contexto a ser usado no servidor web. Isso deixa as classes e recursos do DWR disponíveis no seu contexto de aplicação.

O passo seguinte é configuração do Servlet que despacha as requisições do DWR dentro do contexto. A configuração inicial do        DWR é feita editando o arquivo WEB-INF\web.xml da aplicação. Editaremos o arquivo para cadastrar o DWRServlet presente no arquivo dwr.jar. O código a ser adicionado na seção do web.xml está na Listagem 1. Esse mapeamento faz com que toda requisição que endereçada para o diretório dwr dentro de sua aplicação seja capturada pelo DWRServlet. Este Servlet é o ponto de entrada e o controlador de todo o código do DWR no servidor. É ele quem distribui o código dos proxies JavaScript e quem despacha as chamadas dos proxies para os objetos Java correspondentes que poderão estar na área do contexto, sessão ou serem instanciados a cada requisição.

 

Listagem 1. Código a ser adicionado no web.xml para configurar o uso do DWR.

1.   

2.    dwr-invoker

3.    DWR Servlet

4.    uk.ltd.getahead.dwr.DWRServlet

5.   

6.   

7.   

8.     dwr-invoker

9.     /dwr/*

10.           

 

Você pode testar se a configuração foi feita corretamente acessando o endereço  http://127.0.0.1:8080/chatdwr/dwr/. Se estiver correta, uma página com a mensagem “Classes known to DWR” será mostrada. Isso significa que o DWR está ativo, mas que não está disponibilizando nenhum proxy para ser usado neste contexto. Precisamos criar um outro arquivo de configuração para dizer ao DWR quais são as classes que ele deve disponibilizar como proxies JavaScript.

Porém, antes de fazer isso precisamos criar as classes que conterão as regras centrais do nosso sistema. Estas classes podem ser criadas sem qualquer ligação com o fato de que estaremos usando uma interface com usuário baseada na web. Esta facilidade se dá pelo fato do DWR utilizar apenas as bibliotecas de reflexão do Java (java.lang.reflection) para acessar os objetos e fazer as chamadas aos métodos. Este baixo nível de intrusão também é uma vantagem importante, pois permite a utilização de classes pré-existentes em aplicações AJAX sem nenhuma necessidade de mudança nos respectivos códigos fonte. Quando objetos são usados como parâmetros de entrada ou saída de métodos no proxies, suas respectivas classes devem seguir o padrão JavaBeans para nomeação de métodos de acesso a atributos (setXX, getXX, isXX).

A primeira classe a ser criada representará uma mensagem do chat. Seu código fonte pode ser observado na Listagem 2.

 

Listagem 2. Código da classe Mensagem.

1.   package chatdwr;

2.    

3.   import java.util.Date;

4.    

5.   public class Mensagem {

6.         private Date momento;

7.         private String remetente;

8.         private String texto;

9.    

10.                      public Mensagem() { }

11.                     

12.                      public Mensagem(String remetente, String texto) {

13.                                this.momento = new Date();

14.                                this.remetente = remetente;

15.                                this.texto = texto;

16.                      }

17.                     

18.                      public Date getMomento() {

19.                                return momento;

20.                      }

21.              

22.                      public String getRemetente() {

23.                                return remetente;

24.                      }

25.              

26.                      public String getTexto() {

27.                                return texto;

28.                      }

29.                     

30.             }

 

Note que é uma classe simples, sem nenhuma ligação com qualquer biblioteca externa. Este é o tipo de classe que se convencionou chamar de definidores de POJOs (Plain Old Java Objects). Os POJOs são sempre interessantes de serem utilizados já que facilitam bastante a reutilização do código. A mensagem contém apenas um remetente, conteúdo e a hora da sua criação. Uma segunda classe será definida para representar um usuário do chat. Seu código se encontra na Listagem 3.

 

Listagem 3. Código da classe Usuario.

1.   package chatdwr;

2.   import java.util.ArrayList;

...

Quer ler esse conteúdo completo? Tenha acesso completo