artigo ZK Framework Utilizando Ajax sem Javascript N os últimos anos, as tecnologias utilizadas em aplicações web apresentaram uma notável evolução. Inicialmente tinham-se aplicações cujas camadas de visão eram compostas somente por páginas HTML estáticas que, com o decorrer do tempo, foram gradativamente evoluindo para páginas HTML dinâmicas (DHTML), páginas utilizando Flash, Applets e, por fim, para páginas que incorporavam o uso de Ajax (Asynchronous Javascript and XML). A tecnologia Ajax veio para dar uma nova vida às aplicações web, pois permitiu que elas tivessem um nível de interatividade (usuário x sistema) equiparável às aplicações desktop. Além disso, ao contrário do uso Applets ou Flash, Ajax é baseado nos padrões do browser e Javascript fazendo desnecessária a utilização de algum tipo de plug-in para que a aplicação funcione. Pode-se entender Ajax como uma próxima geração de DHTML, uma vez que a tecnologia é fortemente dependente de Javascript para capturar eventos disparados por alguma ação do usuário e NBOJQVMBS B SFQSFTFOUBÎÍP WJTVBM EF VNB QÈHJOB EPDVNFOU NPEFM PCKFDU o %0. EJOBNJDBNFOUF Thiago Baesso Procaci (thiagoprocaci@gmail.com): é bacharel em Ciência da Computação pela Universidade Federal de Juiz de Fora. Atualmente trabalha como analista de sistemas na Petrobras. Com a maturação da tecnologia Ajax, surgiram vários frameworks baseados nela, sendo o ZK um deles. A ideia principal do ZK Framework é facilitar a incorporação de Ajax nas aplicações web desenvolvidas em Java, de maneira a dispensar qualquer conhecimento de Javascript. Essa facilidade é oriunda dos mecanismos internos do ZK que geram código Javascript de forma transparente para o desenvolvedor. Além desses mecanismos, o ZK possui uma linguagem de marcação, similar ao )5.- WPMUBEB QBSB P VTVÈSJP EFOPNJOBEB ;, 6TFS *OUFSGBDF.BSLVQ -BOHVBHF o ;6.- RVF PGFrece uma maneira simples e intuitiva de criar interfaces para aplicações web. São essas facilidades que, de fato, diferenciam o ZK das demais tecnologias e ferramentas baseadas em Ajax. Este artigo objetiva demonstrar alguns conceitos relacionados ao ZK e apresentar uma aplicação exemplificando seu uso. 62 www.mundoj.com.br
Cada vez mais se faz necessário que as aplicações web sejam intuitivas e fáceis de usar. Esta necessidade está diretamente ligada à camada de visão de tais aplicações. Porém, a criação de aplicações com interfaces ricas exige esforços cada vez maiores. Essa exigência muitas vezes desvia o foco do desenvolvimento que deveria ser, na maior parte do tempo, nas regras de negócio. Com efeito, surgem diversas ferramentas tentando facilitar essa tarefa, sendo uma delas o ZK Framework. Neste artigo, será mostrado como se pode criar aplicações web com interfaces ricas de maneira simples, rápida, sem Javascript e com pouca programação. Como já foi citado anteriormente, o ZK Framework possui uma linguagem de marcação, chamada ZUML, cujo objetivo é facilitar a construção de interfaces web. A figura 1 ilustra o uso da ZUML para a definição de alguns componentes de interface, tais como grid, textbox, datebox, captcha etc. Note que, através do código ZUML da figura 1, é possível com pouco esforço construir uma interface amigável e rica para a aplicação, com todo o código HTML, Javascript e CSS de uma página gerados a partir da ZUML. Outro ponto importante é a possibilidade de configurar os atributos dos componentes através da ZUML. Por exemplo, de acordo com a figura 1, foi definido que o componente decimalbox (caixa de texto que aceita somente números decimais) assumirá valores nos moldes definidos pelo atributo format. Em síntese, pode-se entender ZUML como uma linguagem de marcação de mais alto nível para facilitar criação de interfaces ricas. Entendendo o funcionamento do ZK Framework Para entender melhor o funcionamento do ZK é necessário compreender um pouco de sua arquitetura, ou seja, suas partes e como elas se comunicam. Basicamente o ZK é composto por três importantes módulos que são os responsáveis por incorporar Ajax a uma aplicação. Esses módulos são: o ZK loader, ZK AU (asynchronous update) engine e ZK client engine. Um detalhe importante é que o ZK loader e o ZK AU engine rodam no lado do servidor e são compostos por um conjunto de servlets Java. Em contrapartida, o ZK client engine roda no lado do cliente e é composto por código Javascript. A figura 2 ilustra a arquitetura do ZK. DOM 1 2 Requisição URL Página HTML ZK loader Cria Servidor A interação entre esses módulos que compõem a arquitetura ocorre através dos seguintes passos (enumerados na figura 2): 1. sempre que um cliente faz a requisição de uma página através da URL, o ZK loader interpreta a requisição, gera a página HTML correspondente (baseado no código ZUML referente à URL requisitada) e cria objetos no servidor que permitirão a manipulação da interface da página. Por exemplo, se for definido no código ZUML que uma determinada página terá um grid (como na figura 1), o ZK loader irá gerar o HTML correspondente ao grid e também irá criar um objeto no servidor que permitirá a manipulação do HTML que Browser ZK client engine 3 5 Internet Requisição Ajax Resposta 4 ZK AU engine Atualiza Objetos Figura 2. Arquitetura ZK. 63
corresponde a esse grid; 2. em seguida, o ZK loader envia a página HTML gerada para o cliente juntamente com o ZK client engine. Com já foi citado, o ZK client engine irá residir no lado do cliente e será responsável por monitorar os eventos disparados pelo browser; 3. se qualquer evento for disparado no cliente, o ZK client engine irá enviá-lo (através de uma requisição Ajax) para o ZK AU engine localizado no servidor; 4. o ZK AU engine recebe a requisição Ajax, atualiza os objetos que manipulam os componentes de interface e retorna uma resposta para o cliente, relatando as modificações que página deverá sofrer; 5. assim que o ZK client engine recebe a resposta, ele atualiza a representação visual da página (DOM). Figura 3. Criando novo projeto. Esses passos mostram o funcionamento do ZK e são repetidos enquanto o usuário navegar pela página. Na maioria dos frameworks Ajax existentes na comunidade, o servidor tem um papel passivo. Um servidor tem um papel passivo quando ele é responsável somente por fornecer dados à visão, receber e aceitar requisições do cliente. Essa comunicação Ajax entre cliente e um servidor passivo é complexa e requer muito código Javascript para que ela ocorra (sem mencionar os problemas de compatibilidade entre Javascript e browsers). Em contrapartida, o ZK dá a solução para esses problemas através da criação de objetos no lado do servidor. Esses objetos que ficam no servidor tornam fácil a comunicação Ajax uma vez que toda a manipulação da visão pode ser feita através deles, dispensando a programação Javascript e eventuais problemas de compatibilidade. Daqui pra frente será desenvolvida uma pequena aplicação para demonstrar mais claramente alguns conceitos do framework apresentados. Injetando Ajax em uma aplicação utilizando o ZK Configurações de ambiente Neste momento, será mostrado o funcionamento básico do ZK através de uma pequena aplicação de exemplo. Juntamente com a construção dessa aplicação será elucidado todos os conceitos do framework que foram apresentados anteriormente. Para isso, será utilizado o servidor de aplicação Apache Tomcat 6.0 e a IDE Eclipse Europa. Para começar, é preciso criar um novo projeto. No Eclipse, basta abrir o menu file conforme mostrado na figura 3. Em seguida, será aberta uma tela para escolher o tipo de aplicação que (figura 4) e clique no botão Next. Na sequência, dê um nome para o projeto (no caso do exemplo será zkdemo) e selecione a combo Target RunTime para Apache Tomcat v6.0 (figura 5). Depois, clique no botão Finish que o projeto estará criado. Uma vez criado o projeto, é necessário configurar o ambiente para que o ZK funcione. Para isso, faça o download da última versão do ZK Framework em http://www.zkoss.org/download/ e extraia os jars para a do projeto, cuja configuração é mostrada na Listagem 1. Figura 5. Configuração inicial do projeto. 64 www.mundoj.com.br
Listagem 1. Preparando web.xml. <web-app> <listener> <description> Used to cleanup when a session is destroyed </description> <display-name>zk Session Cleaner</display-name> <listener-class> org.zkoss.zk.ui.http.httpsessionlistener </listener-class> </listener> <servlet> <description>zk loader for evaluating ZK pages</description> <servlet-name>zkloader</servlet-name> <servlet-class> org.zkoss.zk.ui.http.dhtmllayoutservlet </servlet-class> <init-param> <param-name>update-uri</param-name> <param-value>/zkau</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>zkloader</servlet-name> <url-pattern>*.zul</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>zkloader</servlet-name> <url-pattern>*.zhtml</url-pattern> </servlet-mapping> <servlet> <description>the asynchronous update engine for ZK</description> <servlet-name>auengine</servlet-name> <servlet-class> org.zkoss.zk.au.http.dhtmlupdateservlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>auengine</servlet-name> <url-pattern>/zkau/*</url-pattern> </servlet-mapping> <extension>gif</extension> <mime-type>image/gif</mime-type> <extension>html</extension> <mime-type>text/html</mime-type> <extension>htm</extension> <mime-type>text/html</mime-type> <extension>jpeg</extension> <mime-type>image/jpeg</mime-type> <extension>jpg</extension> <mime-type>image/jpeg</mime-type> <extension>js</extension> <zk> <window title= Minha Primeira Aplicação ZK border= normal width= 400px use= com.mundoj.view.hellowindow id= hellowindow > <textbox id= textbox value= Hello World! width= 200px ></textbox> <button label= Trocar Valor onclick= hellowindow.changetextboxvalue() /> </window> </zk> <mime-type>application/x-javascript</mime-type> <extension>png</extension> <mime-type>image/png</mime-type> <extension>txt</extension> <mime-type>text/plain</mime-type> <extension>xml</extension> <mime-type>text/xml</mime-type> <extension>zhtml</extension> <mime-type>text/html</mime-type> <extension>zul</extension> <mime-type>text/html</mime-type> </web-app> A partir deste ponto, já podemos começar a efetivamente desenvolver a aplicação de exemplo. Vale ressaltar que esse exemplo inicial objetiva somente mostrar o funcionamento básico do ZK e alguns conceitos envolvidos. Construindo a aplicação Nessa seção, vamos começar a construir nosso exemplo. O primeiro passo é criar a tela de interação com o usuário, que será definida através - Content do projeto. Esse arquivo deverá conter o código da Listagem 2. Basicamente essa tela inicial será composta por uma janela (componente window da ZUML) que irá conter uma caixa de texto (componente textbox) e um botão (componente button). É importante salientar que a extensão.zul é a utilizada para os arquivos que contêm código ZUML. Listagem 2. hello.zul. 65
Note que, através da Listagem 2, foram configurados vários atributos para os componentes. Por exemplo, no caso da componente window, definimos que ela terá o título Minha Primeira Aplicação ZK, o id hello- que irá manipulá-lo através do atributo use. Observe que no componente window da Listagem 2, o atributo use aponta para a classe Hello- onclick do botão através do método changetextboxvalue. A Listagem 3 Listagem 3. HelloWindow.java. package com.mundoj.view; import org.zkoss.zul.textbox; import org.zkoss.zul.window; @SuppressWarnings( serial ) public class HelloWindow extends Window { public void changetextboxvalue() { Textbox textbox = (Textbox) getfellow( textbox ); if (textbox.getvalue().equals( Hello World! )) textbox.setvalue( Welcome! ); else textbox.setvalue( Hello World! ); Com já foi dito, para cada componente de interface definido em código ZUML, o ZK cria um objeto no servidor que permitirá a manipulação da visão. No caso do exemplo, a cada requisição de um cliente, são criados três objetos no servidor: um para a manipulação da window, um para a textbox e um para o button. Cada um desses objetos criados possui um identificador que pode ser definido através do atributo id (como no código ZUML da Listagem 2) ou gerado automaticamente pelo ZK. Eventualmente surge a necessidade de personalizar o comportamento de um componente, como no caso do componente window do exemplo. Para que isso ocorra, basta criar uma classe que estenda a classe que componente através da adição de métodos, atributos etc. irá manipular a janela e todos os componentes que estão dentro dela, no método changetextboxvalue foi definida a ação que será acionada quando o botão for clicado. Através deste método, vê-se claramente que o objeto que manipula o componente textbox foi recuperado através do id e, em seguida, seu texto (valor) é modificado. A figura 8 mostra o que ocorre por trás das cenas no exemplo quando é clicado o botão Trocar Valor. Com as definições das Listagens 2 e 3, já pode ser iniciada a aplicação e visualizá-la no browser através da URL http://localhost:8080/zkdemo/ hello.zul. A figura 6 mostra como será a interface gerada após iniciar a aplicação. Figura 6. Minha Primeira Aplicação ZK. Agora que temos a aplicação rodando, vamos entender como ocorre o funcionamento dela. O comportamento da aplicação resume-se somente na mudança do texto contido na textbox. Sempre que o usuário clicar em Trocar Valor, o texto da textbox será modificado (figura 7) de simples é tornar fácil o entendimento de como ocorre a manipulação da visão com o ZK. Mais adiante serão mostrados alguns comportamentos mais sofisticados. Figura 7. Comportamento da aplicação. Figura 8. Comportamento da Aplicação com o ZK. Os passos enumerados de 1 a 8 da figura 8 são explicados abaixo: 1. o usuário clica no botão Trocar Valor ; 2. o evento Javascript onclick é disparado; 3. o ZK client engine captura o evento; 4. o ZK client engine envia o evento para o servidor via requisição Ajax; 5. o ZK AU engine recebe o evento e aciona os objetos que serão os responsáveis para executar a ação (trocar o texto); 6. assim que a ação for executada e os objetos forem atualizados, o ZK AU engine é notificado; 7. o ZK AU engine envia a resposta para o ZK client engine com o que deve ser atualizado na página; 8. o ZK client engine atualiza a página (troca o texto). Resumidamente, o ZK client engine e o ZK AU engine trabalham juntos para manter a sincronia entre os elementos das páginas (DOM) e os objetos do servidor para que toda a comunicação Ajax torne uma tarefa fácil para o desenvolvedor. 66 www.mundoj.com.br
Comportamentos mais sofisticados Na seção anterior, foi mostrado um exemplo simples do uso do ZK buscando explicitar os conceitos que foram introduzidos do framework. Nessa seção, vamos mostrar o uso de alguns componentes mais sofisticados do ZK, de maneira a ressaltar seu poder. Para começar o exemplo, vamos criar o arquivo zkdemo.zul dentro da Listagem 4. Listagem 4. zkdemo.zul. <zk> <separator /> <window title= Comportamentos Sofisticados do ZK Framework border= normal width= 800px use= com.mundoj.view.zkdemowindow id= zkdemowindow > <vbox> <menubar> <menu label= Menu > <menupopup> <menuitem label= Sobre ZK onclick= alert(self.label) /> </menupopup> </menu> <menu label= Help > <menupopup> <menuitem label= Help onclick= alert(self.label) /> </menupopup> </menu> </menubar> <label>veja como é fácil usar o ZK</label> <grid> <rows> <row> Nome: <textbox id= nome width= 650px constraint= no empty /> </row> <row> Idade: <intbox width= 150px id= idade constraint= no empty /> </row> <row> Data Nascimento: <datebox id= data constraint= no empty /> </row> <row> Nacionalidade: <listbox id= nacionalidade mold= select > <listitem selected= true > <listcell label= Brasileiro /> </listitem> <listitem> <listcell label= Americano /> </listitem> <listitem> <listcell label= Ingles /> </listitem> <listitem> <listcell label= Outro /> </listitem> </listbox> </row> </rows> </grid> <hbox> <button label= Salvar onclick= zkdemowindow.save() /> <button label= Mostrar Grafico onclick= zkdemowindow.showchart() /> <button label= ZK Framework > <attribute name= onclick >{ Messagebox.show( Ajax sem Javascript, ZK Framework, Messagebox.OK, Messagebox.INFORMATION); </attribute> </button> </hbox> </vbox> <separator /> </window> </zk> por manipular a window definida na Listagem 4. O código da ZKDemo- 67
Listagem 5. zkdemowindow.java. package com.mundoj.view; import java.util.date; import org.zkoss.zul.chart; import org.zkoss.zul.datebox; import org.zkoss.zul.intbox; import org.zkoss.zul.listbox; import org.zkoss.zul.simplepiemodel; import org.zkoss.zul.textbox; import org.zkoss.zul.window; import com.mundoj.dao.pessoadao; import com.mundoj.dao.pessoadaoimpl; import com.mundoj.model.pessoa; @SuppressWarnings( serial ) public class ZKDemoWindow extends Window { private PessoaDao pessoadao = PessoaDaoImpl.getInstance(); private Textbox nometextbox; private Intbox idadeintbox; private Datebox nascimentodatebox; private Listbox nacionalidadelistbox; private Chart chart; // Executado durante a criacao da window public void oncreate() { // pega as referencias de objetos que manipulam a tela nometextbox = ((Textbox) getfellow( nome )); idadeintbox = ((Intbox) getfellow( idade )); nascimentodatebox = ((Datebox) getfellow( data )); nacionalidadelistbox = ((Listbox) getfellow( nacionalidade )); // Salva os dados de pessoa public void save() { String nome = nometextbox.getvalue(); Integer idade = idadeintbox.getvalue(); Date datanascimento = nascimentodatebox.getvalue(); String nacionalidade = nacionalidadelistbox.getselecteditem().getlabel(); Pessoa pessoa = new Pessoa(); pessoa.setnome(nome); pessoa.setidade(idade); pessoa.setdatanascimento(datanascimento); pessoa.setnacionalidade(nacionalidade); pessoadao.save(pessoa); clean(); // Mostra grafico das nacionalidades da pessoas salvas public void showchart() { if (chart == null) { chart = new Chart(); appendchild(chart); chart.setid( grafico ); SimplePieModel model = new SimplePieModel(); chart.setmodel(model); model.setvalue( BRASILEIRO, pessoadao. getbynacionalidade( Brasileiro ).size()); model.setvalue( AMERICANO, pessoadao. getbynacionalidade( Americano ).size()); model.setvalue( INGLES, pessoadao.getbynacionalidade( Ingles ).size()); model.setvalue( OUTRO, pessoadao.getbynacionalidade( Outro ). size()); // Limpa tela private void clean() { nometextbox.setrawvalue(null); idadeintbox.setrawvalue(null); nascimentodatebox.setrawvalue(null); nacionalidadelistbox.setselectedindex(0); Uma vez tendo os códigos das Listagens 4 e 5, pode-se visualizar a aplicação-exemplo em http://localhost:8080/zkdemo/zkdemo.zul. As figuras 9 e 10 mostram como ficará a interface desse exemplo. Em linhas gerais, o exemplo busca ilustrar o uso de outros componentes do ZK e ainda mostrar a facilidade que ele traz para construção interfaces. Rapidamente construímos uma tela com menus, grid, messagebox, chat (gráfico), datebox, entre outros, com pouca programação e nenhum uso de Javascript. Basicamente, o exemplo se trata de um pequeno cadastro de pessoas em que, à medida que são cadastradas, pode-se obter a relação das nacionalidades delas através de um gráfico. O exemplo também apresentou uma forma de incorporar menus em uma janela e como apresentar mensagens para o usuário. Não vamos entrar em detalhes sobre o funcionamento do exemplo, uma vez que ele segue todos os conceitos do framework que já foram apresentados. A ideia é simplesmente que o exemplo sirva como referência inicial para quem desejar aprofundar no assunto e começar a utilizar o ZK. Os fontes estão disponíveis para download no site da revista. 68 www.mundoj.com.br
Considerações finais Neste artigo foi apresentado o ZK Framework, mostrando seus conceitos e um pouco de sua utilização. Buscamos salientar a facilidade que o ZK oferece para a construção de interfaces ricas durante o processo de desenvolvimento de software. É evidente que, assim como todos frameworks existentes na comunidade, o ZK possui limitações. A mais polêmica delas é sobre um possível uso excessivo de memória no servidor devido à criação de objetos para manipulação de páginas. Alguns profissionais da área alegam que quando um sistema necessita ser altamente escalável o ZK não deve ser usado. Porém sabe-se que cada caso é um caso e que sempre antes de iniciar qualquer desenvolvimento de software é necessário analisar se deve ou não utilizar este ou aquele framework. O fato é que o ZK é um framework muito poderoso e pode agilizar bastante algumas tarefas que fazem parte do desenvolvimento de software. Outro ponto positivo do ZK é com relação a sua equipe de desenvolvimento que está sempre muito ativa e buscando constantemente melhorar o framework em todos os sentidos (performance, documentação, Referências