Crie um aplicativo da Web baseado em Ajax dinâmico com o WebSphere Application Server Feature Pack para Web 2.0

O IBM® WebSphere® Application Server Feature Pack para Web 2.0 fornece um rico conjunto de componentes que fornecem aos desenvolvedores uma criação mais fácil e eficiente de aplicativos poderosos com base em Ajax. Este artigo explica como você pode criar um aplicativo da Web que representa gráficos dinâmicos usando o Feature Pack para Web 2.0. Você também verá como é possível combinar recursos principais do Web 2.0 (como Dojo, Web remoting, Web messaging, JSON4J e outros) para criar uma solução com uma rica experiência do usuário, integrando os serviços de backend existentes na arquitetura estilo Ajax.

Li Long Chen, Associate I/T Architect, IBM  

Li Long Chen is working as Associate I/T Architect for IBM Managed Business Process Services solution assets.



Ravi Mani, Executive I/T Architect , IBM  

Ravi Mani is working as an Executive I/T Architect for IBM Global Technology Services solutions.



Elaine Zhan, Adviosory Software Engineer, IBM

Elaine Zhan is working as an Advisory Software Engineer for IBM Managed Business Process Services solution assets.



Chuan Yang, Staff Software Engineer, IBM

Chuan Yang is working as a Staff Software Engineer for IBM Managed Business Process Services solution assets.



Lin Zhi Zou, Staff Software Engineer, IBM  

Lin Zhi Zou is working as a Staff Software Engineer for IBM Managed Business Process Services solution assets.



02/Nov/2009

Introdução

As tecnologias relevantes para o Web 2.0, como Asynchronous JavaScript™ XML (Ajax), Web remoting, Web messaging e outras, se tornaram cada vez mais predominantes nos aplicativos da Web atuais. Comparados com os aplicativos da Web tradicionais, os aplicativos com base em Ajax viabilizam o fornecimento de muito mais agilidade e interatividade. Nesses aplicativos da Web que incorporam a arquitetura Ajax, os usuários não precisam esperar até que a página da Web inteira seja carregada novamente antes de ver os novos resultados do servidor, e geralmente eles podem concluir tarefas com menos etapas em uma única página da Web apresentada de maneira incremental ou sob demanda.

Para atender à necessidade crescente de rapidez no desenvolvimento e na entrega de soluções habilitadas para Ajax-enabled solutions, o IBM WebSphere Application Server Feature Pack para Web 2.0 fornece um amplo conjunto de componentes que permite que você crie aplicativos com base em Ajax de maneira fácil e eficiente. Também fornece uma estrutura com base em padrões abertos para integrar serviços existentes ou ativos de solução em ricos aplicativos de Internet.

Os principais componentes do feature pack incluem:

  • Tempo de execução do cliente/proxy Ajax
  • Adaptador RPC (Remote Procedure Call)
  • Serviço de mensagens da Web
  • Biblioteca JSON4J (JavaScript Object Notation para Java)
  • Biblioteca IBM SOAP
  • Biblioteca IBM Atom
  • Biblioteca IBM OpenSearch
  • Widget IBM Gauge.

Este artigo descreve as etapas para criar um aplicativo de gráfico com base em Ajax usando o Web 2.0 feature pack. Seguindo este exemplo, você poderá ver como os componentes incluídos no feature pack podem ser usados juntos para criar uma solução Web 2.0 completa com uma rica experiência do usuário.

Pré-requisitos

Este exercício assume um conhecimento fundamental de desenvolvimento de aplicativos da Web e familiaridade com o Eclipse ou IBM Rational® Application Developer. Para seguir essas etapas, você precisará ter instalado o WebSphere Application Server Feature Pack para Web 2.0 com êxito em um ambiente operacional WebSphere Application Server (V6.0, 6.1 ou 7.0) corretamente.


Sobre o exemplo de aplicativo dinâmico

O exemplo de aplicativo incluído neste artigo é destinado a demonstrar maneiras possíveis de uso dos componentes principais do feature pack do Web 2.0 para criar um aplicativo com base em Ajax ao mesmo tempo em que é possível solucionar as exigências comerciais em constante mudança. Este exemplo de aplicativo usa gráficos dinâmicos para relatar as quantidades de vendas de marcas automotivas em um determinado período de tempo (em um gráfico de barras) e também permite que os usuários selecionem uma marca específica para visualizar a distribuição de vendas por área (em um gráfico de pizza). Além disso, quando os dados de backend são alterados, os dados atualizados são automaticamente apresentados aos usuários nesses gráficos.

O exemplo de aplicativo, DynamicCharts, tem esses recursos:

  • Fornece uma visualização de gráfico para vendas de carros de várias marcas automotivas.
  • Fornece uma visualização de gráfico para detalhamento de distribuição de vendas por região para uma marca específica.
  • Atualiza os gráficos exibidos em um navegador da Web automaticamente em um intervalo configurável (inicialmente 15 minutos).
  • Fornece um layout flexível que permite que os usuários ajustem o tamanho da visualização principal e a detalhada.

O aplicativo DynamicCharts é criado com esses recursos de feature pack:

  • Tempo de execução do cliente Ajax
  • Adaptador RPC
  • Serviço de mensagens Web
  • JSON4J.

A Figura 1 ilustra as principais funções do aplicativo DynamicCharts, e a Figura 2 representa o fluxo e a estrutura geral do aplicativo.

Figura 1. Funções do exemplo DynamicCharts
Funções do exemplo DynamicCharts
Figura 2. Fluxo e estrutura geral do exemplo DynamicCharts
Fluxo e estrutura geral do exemplo DynamicCharts

Na Figura 2, você pode vir que a lógica do cliente implementada pelo tempo de execução do cliente Ajax:

  • Recupera os dados da interface de fachada do serviço de dados do gráfico -- que pode ser um serviço existente ou ativo de solução -- e é exposto pelo adaptador RPC.
  • Cria ou atualiza os gráficos.
  • Trata os eventos acionados pelos usuários e pelo serviço de mensagens da Web.

As invocações do cliente para adaptador RPC são baseadas em JSON RPC, e os dados retornados são encapsulados em objetos JSON, que podem ser analisados no lado do cliente muito rapidamente. O atualizador de dados de gráfico simula outros aplicativos ou serviços que atualizarão os dados de gráfico sob determinadas circunstâncias, publicando o evento de alteração de dados para clientes por meio de WebSphere Application Server Service Integration Bus (SIBus) e serviços de mensagens da Web. O serviço de dados de gráfico e o atualizador de dados de gráfico dependem do acessador de dados de gráfico para carregar dados ou armazenar dados para uma loja de dados. (Para o objetivo deste artigo, o acessador de dados de gráfico no aplicativo de amostra não conecta para um armazenamento de dados reais.)

As próximas seções o conduzirão pelo processo para criar o aplicativo DynamicCharts. As etapas principais envolvidas serão para:

  1. Importar componentes essenciais
  2. Criar o aplicativo de gráfico usando o Dojo Toolkit
  3. Expor o ChartService a clientes JavaScript pelo adaptador RPC
  4. Publicar atualizações de dados para o navegador da Web com mensagens da Web

O exemplo de aplicativo inteiro, incluindo os arquivos de origem e WAR, e incluído neste artigo para você para fazer download e implantar.


Importar componentes essenciais

  1. Criar um Dynamic Web Project e EAR chamado "DynamicCharts" em seu ambiente de desenvolvimento (significando Eclipse ou Rational Application Developer). A Figura 3 mostra a estrutura de diretório de projeto.
    Figura 3. Estrutura de diretório do projeto DynamicCharts
    Estrutura de diretório do projeto DynamicCharts
  2. Se você está usando o Eclipse, importa o tempo de execução do cliente Ajax e utilitário JARs para a pasta WebContent.
  3. Implemente um conjunto de classes Java™ no pacote de serviço de dados.
  4. Crie a página dynamic-chars.html.

Se você estiver usando o Rational Application Developer V7.5 ou posterior, você não terá que importar explicitamente o tempo de execução do cliente Ajax e utilitário JARs do Web 2.0 porque eles estarão disponíveis em seu projeto quando você habilita o Web 2.0 no Project Faces.

Se você estiver usando o Eclipse para criar este exemplo de aplicativo, mais algumas etapas serão necessárias:

  1. Copie a pasta ajax-rt_1.X do diretório raiz de instalação do feature pack Web 2.0 (geralmente <app_server_root>/web2fep) para a pasta WebContent do seu projeto recentemente criado (Figura 4).
    Figura 4. Tempo de execução do cliente Ajax
    Tempo de execução do cliente Ajax
  2. Localize esses cinco arquivos JAR na pasta optionalLibraries no diretório raiz de instalação do feature pack Web 2.0 e copie-os para a pasta WebContent/WEB-INF/lib do seu projeto (Figura 5):
    • commons-logging-1.0.4.jar
    • RPCAdapter.jar
    • RPCAdapter-annotation.jar
    • retroweaver-rt-2.0.jar
    • webmsg_applib.ja
    Figura 5. JARS do utilitário Web 2.0
    JARS do utilitário Web 2.0

Quando as bibliotecas exigidas tiverem sido importadas em seu projeto, você poderá começar com seu código de aplicativo.


Crie o aplicativo de gráfico usando o Dojo Toolkit

O Dojo Toolkit é um kit de desenvolvimento de software Ajax de código aberto, modular, flexível e poderoso que permite que você crie facilmente recursos dinâmicos em páginas da Web. O feature pack Web 2.0 incorpora o Dojo Toolkit 1.1 e extensões IBM, como o tempo de execução do cliente Ajax. Nesta seção, você verá como é fácil usar o Dojo Toolkit para implementar uma página de gráfico que tenha interações do usuário e serviços de backend.

  1. Crie uma página HTML e carregue o script Dojo básico (ajax-rt_1.X/dojo/dojo.js) com a tag <script/> na seção principal. Isso fornece as funções principais do Dojo, bem como o acesso a todos os outros recursos Dojo.
  2. Importe os estilos Dojo na tag <style/> e declare os pacotes Dojo que serão mencionados nesta página da Web com dojo.require(…), como pode ser visto na Listagem 1.
    Listagem 1. Declarando os temas e os componentes do Dojo
    <style type="text/css">
        @import "ajax-rt_1.X/dojo/resource/dojo.css";
        @import "ajax-rt_1.X/dijit/themes/tundra/tundra.css";
        @import "dynamic-charts.css";
    </style>
    
    <script type="text/javascript" src="ajax-rt_1.X/dojo/dojo.js" 
        djConfig="isDebug: false, parseOnLoad: true, usePlainJson: true"></script>
    
    <script type="text/javascript">
        dojo.require("dojox.charting.Chart2D");
        dojo.require("dijit.layout.BorderContainer");
        dojo.require("dijit.layout.ContentPane");
        dojo.require("dojo.rpc.JsonService");
        dojo.require("dojox.cometd");
        dojo.require("dojox.charting.themes.PlotKit.orange");
    </script>
  3. Depois disso, defina o layout de página na seção do corpo do arquivo HTML (Listagem 2):
    • O widget de layout Dojo dijit.layout.BorderContainer é usado aqui para layout de página, dividido em dois dijit.layout.ContentPanes, um para o gráfico de vendas de carro e outro para o gráfico de distribuição.
    • O atributo splitter do segundo dijit.layout.ContentPane é definido como verdadeiro, o que permite que o usuário altere e ajuste as larguras das duas regiões.
    • Em cada região, uma ou duas tags <div> são incorporadas como os nós nos quais você criará um grupo de botão de opção ou gráfico.

    Saiba que o dijit.layout.SplitContainer original foi reprovado no Dojo 1.1 e que o dijit.layout.BorderContainer foi introduzido como substituição.

    Listagem 2. Definindo o layout da página do gráfico
    <div dojoType="dijit.layout.BorderContainer" design="sidebar" id="main">
        <div dojoType="dijit.layout.ContentPane" region="center" id="sale_pane">
            <p>Car Sale</p>
            <div id="car_sale_chart"></div>
        </div>
        <div dojoType="dijit.layout.ContentPane" 
            region="trailing" splitter="true" id="distribution_pane">
            <p>Choose a brand to view sale distribution by area</p>
            <div id="brand_picker"></div>
                <div id="distribution_by_area"></div>
            </div>
    </div>
  4. Agora você está pronto para formular o código JavaScript. As funções JavaScript a serem implementadas estão resumidas nesta tabela:
    FunçãoFunção/evento de disparoDescrição da tarefa
    init()Evento de carregamento de páginaChame getSaleData() e registre o controlador de mensagens da Web
    webmsgHandler(…)Serviço de mensagens da WebProcesse o evento acionado pelo serviço de mensagens da Web
    getSaleData()init()Registre o controlador JSON RPC e carregando os dados de vendas
    showCarSale(…)getSaleData()Analise os dados de vendas retornados e chame as funções para criar gráficos
    makeSaleChart(…)showCarSale()Crie gráfico de vendas
    makeBrandPicker(…)showCarSale()Crie o grupo de rádio da marca e registre o controlador em clique
    brandPickerHander()Ação do usuárioIdentifique as funções de chamada e marca selecionadas para criar gráficos
    getDistributionData(…)brandPickerHander()Registre o controlador JSON RPC e carregando dados de distribuição
    makeDistributionChart(…)getDistributionData(…)Crie o gráfico de distribuição

    Em seguida, é necessário carregar e analisar os dados de vendas de carros do serviço de backend. O fragmento JavaScript na Listagem 3 ilustra como chamar o serviço de dados de gráfico por meio da chamada JSON RPC e adaptador RPC. Você só precisa criar uma instância do serviço Dojo JSON com a URL determinada exposta pelo adaptador RPC.

    O primeiro parâmetro:

    /DynamicCharts/RPCAdapter/jsonrpc/ChartDataService/getCarSale

    significa chamar o método getCarSale() da classe ChartDataService (isso será explicado posteriormente) e, em seguida, registre a função de retorno de chamada showCarSale(...) para a instância do serviço JSON, no qual os dados formatados para JSON retornados são analisados e os dados de marca e quantidade são colocados em arrays respectivamente.

    Há outra opção para executar uma chamada JSON RPC -- usando o wrapper Dojo XMLHTTPRequest (dojo.xhr) -- mas que exige mais codificação e não é tão objetivo quanto o que é mostrado na Listagem 3.

    Listagem 3. Carregamento e análise de dados de vendas de carros
    // Retrieve the sale data via JSON RPC invocation and make
    // the charts.
    function getSaleData() {
        // Call the json service to retrieve the car sale data
        var json_svc = new dojo.rpc.JsonService(
            "/DynamicCharts/RPCAdapter/jsonrpc/ChartDataService/getCarSale");
        json_svc.getCarSale().addCallback(showCarSale);
    }
    
    // Parse the sale data and create the sale chart and the brand picker
    // function showChart(data, ioArgs) {
    function showCarSale(sale_data) {
        // Parse the data returned from the server
        var sale_brands = new Array();
        var sale_quantities = new Array();
    for (var i=0;i<sale_data.length;i++) {
            sale_brands[i] = {value:(i+1), text:sale_data[i].brand};
            sale_quantities[i] = sale_data[i].quantity;
        }
    	
        // Make the auto sale chart
        makeSaleChart(sale_brands, sale_quantities);
    	
        // Make the brand picker
        makeBrandPicker(sale_brands);
    }
  5. Assim que a data do gráfico é carregada e analisada, a função makeSaleChart será chamada para criar o gráfico de vendas (Listagem 4). O objeto Dojo Chart2D geralmente é composto de quatro partes: tema, plotagem, eixo e série (dados). A chamada addPlot determina quais tipos de gráficos que você vai produzir. Há uma variedade de tipos de plotagem disponíveis. Os gráficos mais usados são linhas, barras, colunas, áreas, grade, marcadores, de pizza, empilhado e assim por diante. Aqui, "Colunas" é usado como gráfico de barras vertical para as vendas de carros. As funções addPlot e addAxis levam dois parâmetros: um nome e um array de argumento. A função addSeries aceita parâmetro adicional: um array de série de dados.
    Listagem 4. Criando o gráfico de vendas de carros
    // Create the sale chart
    function makeSaleChart(brands, quantities) {	
        if (sale_chart == undefined) {
            // Make the sale chart for the first request of a given user
            sale_chart = new dojox.charting.Chart2D("car_sale_chart");
            sale_chart.setTheme(dojox.charting.themes.PlotKit.orange);
            sale_chart.addPlot("default", {type:"Columns", gap:2});
            sale_chart.addAxis("x", {labels:brands});
            sale_chart.addAxis("y", {vertical:true, includeZero:true, max:50});
            sale_chart.addSeries("Auto Sale", 
                quantities, {stroke:{color:"black"}, fill:"lightblue"});
            sale_chart.render();	
        }
        else {
            // Update the sale chart
            sale_chart.updateSeries("Auto Sale", quantities);
            sale_chart.render();			
        }
    }

    O grupo de rádio do selecionador de marcas é criado na Listagem 5, com base nas marcas retornadas ao criar o gráfico de vendas acima.

    Listagem 5. Criando o selecionador de marcas
    // Create the brand picker
    function makeBrandPicker(brands) {
        var picker = dojo.byId("brand_picker");
        var pickerNode = dojo.byId("picker_node");
        if (pickerNode == undefined) {
            pickerNode = document.createElement("div");
            dojo.attr(pickerNode, "id", "picker_node");
            for (var i=0;i<brands.length;i++) {
                var option;
                // Different code for IE and FF respectively
                if (dojo.isIE) {
                    option = document.createElement("<input name='auto_brand'>");
                }
                else {
                    option = document.createElement("input");
                    dojo.attr(option, "name", "auto_brand");
                }
                // Create the radio option
                dojo.attr(option, "type", "radio");
                dojo.attr(option, "id", brands[i].text);
                dojo.attr(option, "value", brands[i].text);
                dojo.attr(option, "dojoType", "dijit.form.RadioButton");
                // connect onclick to the picker handler
                dojo.connect(option, "onclick", brandPickerHandler);    
                pickerNode.appendChild(option);
                // Create the label
                var lbl = document.createElement("label");
                dojo.attr(lbl, "for", brands[i].text);
                var txt = document.createTextNode(brands[i].text);
                lbl.appendChild(txt);
                pickerNode.appendChild(lbl)
                var nl = document.createElement("br");
                pickerNode.appendChild(nl);
            }
            picker.appendChild(pickerNode);
    	}
        else {
            // if the picker node exists, just refresh the selection
            brandPickerHandler();    
        }
    }

    Há somente operações HTML DOM (Document Object Model) gerais na função makeBrandPicker. A única coisa de que você deve estar ciente é se a função brandPickerHander está registrada como o controlador em clique usando dojo.connect, que localizará a marca selecionada pelo usuário e acionará a criação ou atualização do gráfico de distribuição, como pode ser visto na Listagem 6.

    Listagem 6. Processando o evento de seleção de marcas
    // Brand picker event handler
    function brandPickerHandler() {
        // Find out the selected brand
        var pickerNode = dojo.byId("picker_node");
        var children = pickerNode.childNodes;
        var selected_brand;
        for (var i=0;i<children.length;i++) {
            if (children[i].checked != undefined && children[i].checked == true) {
                selected_brand = children[i].value;
                // Retrieve the updated distribution data and refresh the distribution
                // chart based on the selected brand
                getDistributionData(selected_brand);
                break;
            }
        }
    }
  6. O carregamento de dados de distribuição e a criação do gráfico de distribuição são semelhantes aos dos dados de vendas e do gráfico, exceto pelo fato de que o tipo de plotagem usado é Gráfico de pizza, como pode ser visto na Listagem 7.
    Listagem 7. Carregando os dados de distribuição e criando o gráfico de distribuição
    // Retrieve the distribution data via JSON RPC invocation and 
    // make the distribution chart.
    function getDistributionData(brand) {
        // Call the json service to retrieve the distribution data
        var json_svc = new dojo.rpc.JsonService(
            "/DynamicCharts/RPCAdapter/jsonrpc/ChartDataService/getDistributionByArea");
        json_svc.getDistributionByArea(brand).addCallback(makeDistritubtionChart);
    }
    
    // Create the distribution chart
    function makeDistritubtionChart(dist_data) {
        // Parse the distribution data
        var dist_percentage = new Array();
        for (var i=0;i<dist_data.length;i++) {
            var data = dist_data[i]
            dist_percentage[i] = {
            y:data.percent,text:data.region+"("+Math.round(data.percent)+"%)",
            color:data.color};
        }
    
        if (dist_chart == undefined) {
            // Make the distribution chart for the first request of a given user
            dist_chart = new dojox.charting.Chart2D("distribution_by_area");
            dist_chart.setTheme(dojox.charting.themes.PlotKit.orange);
            dist_chart.addPlot("default", 
                {type:"Pie",font:"normal normal bold 6pt sans-serif",fontColor:"white"});
            dist_chart.addSeries("Area Distribution", dist_percentage);
            dist_chart.render();	
        }
        else {
            // Update the distribution chart
            dist_chart.updateSeries("Area Distribution", dist_percentage);
            dist_chart.render();
        }
    }
  7. A última parte da implementação JavaScript é definir a função init que será chamada imediatamente após o carregamento da página. Essa função cuida da inicialização global, como a inicialização do servlet de mensagens da Web, registrando o controlador de mensagens da Web e se inscrevendo no tópico /charttopic, bem como chamando outras funções para carregar os dados de vendas. (Mais informações sobre mensagens da Web poderão ser encontradas nas próximas seções.)
    Listagem 8. Iniciando o controlador de mensagens da Web
    // Web Messaging handler.
    function webmsgHandler(msg) {
        if (msg.data == "UPD") {
            // Get the updated sale data from the backend
            getSaleData();
        }
    }
    
    // Perform initialization when loading the page.
    function init() {
        // Use the "tundra" style
        dojo.addClass(dojo.body(), "tundra");
    	
        // Get the sale data from the backend
        getSaleData();
    	
        // Initalize the web messaging client
        dojox.cometd.init("webmsgServlet");
        dojox.cometd.subscribe("/charttopic", window, "webmsgHandler");
    }

Exponha o ChartService a clientes JavaScript por meio do adaptador RPC

O adaptador RPC (Web remoto) oferece a capacidade, para JavaScript ou código do lado do cliente, de chamar diretamente a lógica do lado do servidor por meio de uma chamada JSON RPC. Isso significa que os métodos POJO podem ser chamados facilmente pelos aplicativos Ajax, sem reestruturar as implementações existentes para clientes leves.

A Listagem 9 mostra o EJB ChartData que fornecerá o serviço de dados de gráfico expostos por meio do adaptador RPC. Dois métodos estão disponíveis nesta classe Java:

  • getCarSale() para recuperar os dados de vendas para todas as marcas de automóveis.
  • getDistributionByArea(...) para recuperar os dados de distribuição para a marca selecionada por meio do componente de acesso de dados de gráfico ChartDataAccessor.
Listagem 9. Implementando o serviço de gráfico
public class ChartData{
	
    private static final Logger logger = Logger.getLogger("dataservice.ChartData");
	
    /**
     * Gets the sale data of all auto brands
     * @return sale data for all brands
     */
    public CarSale[] getCarSale() {
        // Retrieve the sale data with the chart DAO.
        logger.log(Level.INFO, "Retrieving car sale data for all brands.");
        return ChartDataAccessor.getInstance().loadSaleData();
}
	
    /**
 * Gets the distribution data by area for a given auto brand.
 * @param brand
 * @return distribution data for the given brand
*/
    public AreaDistribution[] getDistributionByArea(String brand) {
        // Retrieve the distribution data with the chart DAO.
        logger.log(Level.INFO, "Retrieving distribution data for " + brand + ".");
        return ChartDataAccessor.getInstance().loadDistributionDataByBrand(brand);
    }	
}

Para publicar esses métodos nos clientes Ajax, é necessário criar o arquivo de configuração RpcAdapterConfig.xml na pasta WebContent/Web-INF no projeto:

  1. Se estiver usando o Rational Application Developer V7.5, navegue para Project => Services => Expose RPC Adapter Service e não será necessário criar manualmente o arquivo de configuração. Especifique <default-format /> para JSON por que você deseja que os dados retornados no formato JSON sejam processados pelo JavaScript direta e rapidamente.
  2. Defina o nome do serviço e da implementação como ChartDataService e dataservice.ChartData respectivamente e exponha os dois métodos getCarSale() e getDistributionByArea() em <methods />.

    Além de definir os métodos expostos em RpcAdapterConfig.xml, há outra maneira de expor o serviço do adaptador RPC, com a classe EJB implementando a interface com.ibm.webphere.rpcadapter.SelfBeanInfo e fornecendo as informações dos métodos expostos no método getBeanDescriptorInfo().

    Listagem 10. Publicando o serviço de gráfico em RpcAdapterConfig.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <rpcAdapter 
      xmlns="http://www.ibm.com/xmlns/prod/websphere/featurepack/v6.1/RpcAdapterConfig" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <default-format>json</default-format>
          <services>
              <pojo>
                  <name>ChartDataService</name>
                  <implementation>dataservice.ChartData</implementation>
                  <description>The facade for the chart data service.</description>
                  <methods>
                      <method>
                      <name>getCarSale</name>
                          <description>Gets all the car sale data.</description>
                          <http-method>GET</http-method>
                      </method>
                      <method>
                          <name>getDistributionByArea</name>
                          <description>Gets the distribution data.</description>
                          <http-method>GET</http-method>
                          <parameters>
                              <parameter>
                                  <name>brand</name>
                                  <description>a specific brand</description>
                              </parameter>
                          </parameters>
                      </method>
                  </methods>
              </pojo>
          </services>
    </rpcAdapter>
  3. A última etapa para publicar o serviço de dados de gráfico é configurar o arquivo web.xml de forma que o servlet com.ibm.websphere.rpcadapter.RPCAdapter seja exposto neste endereço da Web:
    http://<host>:<port>/DynamicCharts/RPCAdapter/*

    Para isso, adicione a configuração do servlet na Listagem 11 ao arquivo web.xml.

    Listagem 11. Configurando o Servlet do adaptador RPC em web.xml
    <servlet>
        <display-name>RPCAdapter</display-name>
        <servlet-name>RPCAdapter</servlet-name>
        <servlet-class>com.ibm.websphere.rpcadapter.RPCAdapter</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RPCAdapter</servlet-name>
        <url-pattern>/RPCAdapter</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>RPCAdapter</servlet-name>
        <url-pattern>/RPCAdapter/*</url-pattern>
    </servlet-mapping>
  4. Agora você pode testar o serviço de gráfico pelo adaptador RPC. Abra essas URLs no seu navegador da Web e faça download dos resultados:
     http://<host>:<port>/DynamicCharts/RPCAdapter/httprpc/ChartDataService/getCarSale
    http://<host>:<port>/DynamicCharts/RPCAdapter/httprpc/ChartDataService/
            getDistributionByArea?brand=BMW

Publique as atualizações de dados nos navegadores da Web com mensagens da Web

O serviço de mensagens da Web conecta um navegador ao WebSphere Application Server SIBus para evento push do lado do servidor por meio de uma implementação publicar/inscrever-se, facilitando a criação de aplicativos da Web com atualizações de dados em tempo real, como cotações de preço de ações, lances em leilões e atualizações automáticas de notícias.

A comunicação cliente/servidor é atingida por meio de um protocolo de roteamento de mensagens com base em HTTP chamado no protocolo Bayeux. Cometd é um projeto da Dojo Foundation para fornecer implementações do protocolo Bayeux em JavaScript e outros idiomas. O código na Listagem 8 usa Dojo Cometd para inicializar o servlet de mensagens da Web, se inscrever no tópico /charttopic e registrar o controlador de mensagens da Web no lado do cliente. Há poucos códigos que precisam ser gravados para habilitar o serviço de mensagens da Web no lado do servidor, exceto para algumas configurações da mensagem da Web e SIBus. (As instruções de implementação na próxima seção explicam como definir o parâmetro webmsgenabled e criar o chartbus SIBus no servidor de aplicativos.

Há também um arquivo de configuração de mensagens da Web webmsg.json em WebContent/WEB-INF do projeto DynamicCharts (Listagem 12). Neste arquivo, busName é definido como chartbus. Para o propósito deste exemplo, o clientCanPublish é definido como falso porque a publicação do lado do servidor é suficiente aqui.

Listagem 12. Configurando o serviço de mensagens da Web em webmsg.json
{
    "WebMsgServlet": 
    {  
        "busName": "chartbus", 
        "destination": "Default.Topic.Space", 
        "clientCanPublish": false,
        "longPollTimeout": 30
    }
}

Vamos dar uma olhada na implementação do atualizador de dados do gráfico e como publicar um evento de servidor para clientes com o connection factory do tópico JMS.

A classe ChartDataUpdater implementa a interface CommonJ Timer do TimerListener (consulte Resources). Quando o cronômetro expirar, o método timerExpired do objeto ChartDataUpdater será executado para simular as atualizações de dados do gráfico por outras soluções ou serviços e, em seguida, publicará uma mensagem nos clientes da Web. Para ajudar na publicação para clientes de mensagens da Web, uma API de publicação será fornecida na biblioteca do utilitário de aplicativos de mensagens da Web. A Listagem 13 demonstra o uso da API de publicação; ou seja, publicando a mensagem UPD através do canal / tópico de gráfico Bayeux encapsulado em BayeuxJmsTextMsg.

Listagem 13. Implementando a interface timerExpired para o atualizador de dados do gráfico
/**
* Perform the scheduled task at the given interval, implementing 
* the interface of TimerListener.
*/
public void timerExpired(Timer timer) {
    logger.log(Level.INFO, "Entering timer listener.");
    try {
        // Update the data
        logger.log(Level.INFO, "Updating chart data.");
        ChartDataAccessor cda = ChartDataAccessor.getInstance();
        cda.storeSaleData(simulateSaleData());
        cda.storeDistributionData(simulateDistributionData());
        // Notify the clients of the chart data updates
        logger.log(Level.INFO, "Notifying Web browser clients of data updates");
        publisher.publish(new BayeuxJmsTextMsg("/charttopic", "UPD"));
    } catch (PublisherException e) {
        e.printStackTrace();
        logger.log(Level.SEVERE, e.getMessage());
    }
logger.log(Level.INFO, "Exiting timer listener.");
}

O início, o planejamento e a parada do atualizador de dados do gráfico são feitos chamando TimerManager de CommonJ Timer (Listagem 14).

Listagem 14. Implementando os métodos de início/parada do atualizador de dados do gráfico
/**
* Starts the chart data updater.
*
*/
public void startUpdater() {
    try {
        if (!timerRunning) {
            InitialContext ctx = new InitialContext();
            tmgr = (TimerManager)ctx.lookup("java:comp/env/tm/default");		
            tmgr.schedule(this, 5, UPDATE_INTERVAL);
            timerRunning = true;
            logger.log(Level.INFO, "The chart data updater is started.");
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
        logger.log(Level.SEVERE, e.getMessage());
    } catch (IllegalStateException e) {
        e.printStackTrace();
        logger.log(Level.SEVERE, e.getMessage());
    } catch (NamingException e) {
        e.printStackTrace();
        logger.log(Level.SEVERE, e.getMessage());
    }		
}
	
/**
 * Stops the chart data updater.
 *
 */
public void stopUpdater() {
    if (timerRunning) {
        if (tmgr != null) {
            tmgr.stop();
            logger.log(Level.INFO, "The chart data updater is stopped.");
        }
    }
}

Além disso, você precisa obter a instância do Publisher, inicializar o ChartDataUpdater com o publicador e iniciar o ChartDataUpdater no método init do servlet de inicialização. Fora isso, você precisa encerrar o ChartDataUpdater no listener de contexto do servlet quando o contexto de servlet for destruído (Listagem 15).

Listagem 15. Implementando o gerenciamento do ciclo de vida do atualizador de dados do gráfico
/* (non-Javadoc)
 * @see javax.servlet.GenericServlet#init()
 */
public void init() throws ServletException {
    // Call the init() of the super class
    super.init();
    // Get and initialize the instance of ChartDataUpdater (pass in the publisher)
    ServletContext servletContext = getServletConfig().getServletContext();
Publisher publisher = (Publisher) servletContext.getAttribute(
        JmsPublisherServlet.PUBLISHER_SERVLET_CONTEXT_KEY);
    ChartDataUpdater cdu = new ChartDataUpdater(publisher);
    cdu.startUpdater();
    // Keep the chart data updater, and clean it up when the context is destroyed 
    servletContext.setAttribute(ChartDataUpdater.UPDATER_KEY, cdu);
}   


/* (non-Java-doc)
 * @see javax.servlet.ServletContextListener#contextDestroyed(ServletContextEvent arg0)
 */
public void contextDestroyed(ServletContextEvent arg0) {
    // Stop the timer when context is destroyed
ChartDataUpdater cdu = (ChartDataUpdater) arg0.getServletContext()
    .getAttribute(ChartDataUpdater.UPDATER_KEY);
    if (cdu != null) {
        cdu.stopUpdater();
    }
}

Finalmente, coloque as configurações do servlet para o sistema de mensagens JMS Publisher e Web, e as referências de recursos para o Connection Factory do tópico CommonJ Timer e JMS (Listagem 16).

Listagem 16. Configurando a mensagem da Web em web.xml
<servlet>
    <description></description>
    <display-name>Publisher</display-name>
    <servlet-name>Publisher</servlet-name>
<servlet-class>
        com.ibm.websphere.webmsg.publisher.jndijms.JmsPublisherServlet
    </servlet-class>
    <init-param>
        <description></description>
        <param-name>CONNECTION_FACTORY_JNDI_NAME</param-name>
        <param-value>java:comp/env/jms/ChartPublish</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
    <description/>
    <display-name>WebMsgServlet</display-name>
    <servlet-name>WebMsgServlet</servlet-name>
    <servlet-class>com.ibm.websphere.webmsg.servlet.WebMsgServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>WebMsgServlet</servlet-name>
    <url-pattern>/webmsgServlet</url-pattern>
</servlet-mapping>
<resource-ref id="ResourceRef_1224495798546">
    <description></description>
    <res-ref-name>tm/default</res-ref-name>
    <res-type>commonj.timers.TimerManager</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
<resource-ref id="ResourceRef_1224558884500">
    <description></description>
    <res-ref-name>jms/ChartPublish</res-ref-name>
    <res-type>javax.jms.TopicConnectionFactory</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

Você concluiu o desenvolvimento da amostra DynamicCharts. A próxima seção explica como é possível exportar o arquivo WAR inteiro e como implementar e executar este exemplo.


Faça download e implemente o exemplo

O arquivo WAR do DynamicCharts, incluindo o código de origem, é fornecido com este artigo para download. Estes arquivos foram verificados no Internet Explorer e Firefox com WebSphere Application Server V6.1.0.13 com PK56881. Certifique-se de importar todos os arquivos JAR dependentes e o tempo de execução Ajax antes da implementação.

Para instalar o exemplo de DynamicCharts:

  1. Verifique se o WebSphere Application Server Feature Pack para Web 2.0 está instalado e operando corretamente.
  2. Ative o serviço do sistema de mensagens da Web:
    1. Efetue logon no console administrativo do WebSphere Application Server e navegue até Servers => Application servers. Selecione o servidor no qual o DynamicChartsEAR.ear será implementado.
    2. Expanda Configurações do Contêiner da Web, selecione Web container transport chains e, em seguida, selecione a cadeia de transporte WCInBoundDefault.
    3. Selecione Web container inbound channel e, em seguida, selecione Customer Properties.
    4. Clique em New e insira webmsgenabled para a propriedade do nome e true para o valor.
    5. Clique em Apply e, em seguida, Save para salvar as informações de repositório.
    6. Reinicie o servidor de aplicativos.
  3. Crie e configure o SIBus do barramento do gráfico:
    1. Efetue logon no console de administração e navegue até Service integration => Buses.
    2. Clique em New e insira o chartbus para o nome e aceite todos os padrões restantes.
    3. Clique em Next e, em seguida, em Finish.
    4. Clique em Bus members em Topologia na página de detalhes do barramento de gráfico.
    5. Clique em Add e, em seguida, selecione o servidor onde deseja que o DynamicChartsEAR.ear seja instalado. Clique em Next.
    6. Aceite os padrões e clique em Next e, em seguida, em Next novamente e depois em Finish.
    7. Salve as alterações no repositório.
    8. Reinicie o servidor de aplicativos.
  4. Crie o connection factory do tópico para DynamicCharts:
    1. Efetue logon no console de administração e navegue até Resources => JMS => Topic connection factories.
    2. Selecione um escopo de nível de servidor.
    3. Clique em New. Selecione Default messaging provider e clique em OK.
    4. Insira DynamicCharts para o nome, jms/ChartPublish para o nome JNDI e chartbus para o Bus name e mantenha todos os padrões restantes.
    5. Clique em Apply e, em seguida, clique em Save para salvar as informações de repositório.
  5. Instale o DynamicChartsEAR.ear:
    1. Efetue logon no console de administração e navegue até Applications => Install New Application.
    2. Navegue até seu sistema de arquivos e selecione DynamicChartsEAR.ear e clique em Next.
    3. Aceite os padrões e clique em Next e, em seguida, em Next novamente e depois em Finish.
    4. Clique em Save para salvar a configuração principal.
    5. Inicie o DynamicChartEAR.
    6. Ative esta URL: http://<host>:<port>/DynamicCharts/dynamic-charts.html.

Conclusão

O WebSphere Application Server Feature Pack para Web 2.0 fornece uma solução completa para a maioria dos requisitos comuns da construção de aplicativos baseados em Ajax. Este artigo explicou como criar gráficos dinâmicos com o Dojo Toolkit, como você pode reutilizar um serviço existente com o adaptador RPC e como pode integrar outros aplicativos e publicar as mudanças de dados nos clientes com o sistema de mensagens da Web e o SIBus. As considerações e dicas apresentadas aqui ajudarão no melhor entendimento do Web 2.0 para que possa construir ou aprimorar rapidamente e com êxito seus próprios aplicativos baseados em Ajax.

Recursos

Aprender

Obter produtos e tecnologias

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=WebSphere
ArticleID=442574
ArticleTitle=Crie um aplicativo da Web baseado em Ajax dinâmico com o WebSphere Application Server Feature Pack para Web 2.0
publish-date=11022009