Integrando o Adobe Flex com o IBM WebSphere Portal

Este artigo mostra como integrar o Adobe® Flex no IBM® WebSphere® Portal usando amostras. É possível usar o Adobe Flex como uma solução do lado do cliente para renderizar a interface com o usuário dos portlets, superar as limitações do HTML e aprimorar grandemente a experiência do usuário dentro do portal. Este artigo também mostra como chamar e consumir objetos JSON dentro de um aplicativo Flex em execução no WebSphere Portal.

Shade El-Hadik, Senior Consulting IT Specialist , IBM  

Shade El-Hadik é especialista senior em consultoria de TI para IBM WebSphere Portal, IBM Lotus Web Content Management e prática de e-commerce. Trabalhou no desenvolvimento do J2EE e da Web por mais de cinco anos e desenvolveu diversos aplicativos de portal para a família de produtos do WebSphere. É possível entrar em contato com Shade pelo endereço de e-mail saelhadi@us.ibm.com.



30/Nov/2009

Nota do editor: Conhece muito sobre esse tópico? Deseja compartilhar seu conhecimento? Participe hoje do programa de wiki do software IBM Lotus.

Introdução

Este artigo explica como integrar o Adobe Flex com um portlet do IBM WebSphere Portal. O ponto de partida é a criação de um projeto do Flex usando o Adobe Flex Builder e, em seguida, ele mostra como criar um serviço da Web. Por fim, ele integra tudo em uma página de portlet. Este texto aborda como exibir e atualizar uma lista simples de funcionários. Usando a mesma ideia, ele apresenta um segundo exemplo de como fazer com que o aplicativo do Flex se comunique com o objeto JSON, usando um servlet de backend, por meio da estrutura do WebSphere Portal. Este artigo contém todo o código necessário para ambos os exemplos, além de explicações linha por linha. Ele demonstra que a integração de um rich Internet application (RIA) com o WebSphere Portal usando o portlet JSR-168 é um processo viável e transparente, graças ao serviço Flex HTTP, ao serviço da Web (SOA) e às serializações do JSON.

Os Rich Internet applications (RIAs) oferecem uma experiência cativante que melhora a satisfação do usuário e aumenta a produtividade. Usando o amplo alcance da Internet, os RIAs podem ser implementados em navegadores e desktops. O Adobe Flex é uma estrutura de software livre, gratuita, para criação de aplicativos Web altamente interativos, expressivos, que podem ser implementados, de modo consistente, em todos os principais navegadores, desktops e sistemas operacionais. Oferece um modelo moderno de linguagem e programação baseados em padrões, que suporta padrões de design comuns. O MXML, uma linguagem declarativa baseada em XML, descreve o layout e os comportamentos da interface com o usuário; e o ActionScript3, uma linguagem de programação sofisticada orientada a objetos, cria a lógica do cliente. O Flex apresenta uma aparência consistente nos diversos navegadores.

O WebSphere Portal é um aplicativo da Web que agrega conteúdo de diferentes recursos a uma UI integrada. Os portais também provêem recursos de personalização e conexão única por meio de uma infraestrutura de segurança integrada própria, além de se integrarem a soluções de fornecedores independentes. O JSON (JavaScript™ Object Notation) é um formato leve de intercâmbio de dados. Reduz o tráfego HTTP introduzindo um novo formato para o intercâmbio de dados entre aplicativos servidor e cliente.


Pré-requisitos

É necessário ter um conhecimento sólido das seguintes tecnologias:

  • Java™ Runtime Environment 1.5.0 ou posterior
  • Servidor da Web (como o IBM WebSphere Application Server V6.0 ou o Apache Tomcat V6.0)
  • WebSphere Portal V6.0
  • IBM Rational® Software Architect V7.0 ou posterior
  • Adobe Flex Builder (V2.0 ou posterior)
  • Servidor MySQL V5.0 ou posterior

Executando um aplicativo do Flex em um serviço da Web (SOA) no WebSphere Portal

Este exemplo mostra como executar um aplicativo do Adobe Flex. O aplicativo chama um serviço da Web denominado EmployeesDB, que se conecta a um banco de dados por meio do Java Database Connectivity (JDBC). O serviço da Web apresenta dois métodos:

  • O nome do primeiro é getEmployees() e ele retorna uma lista de nomes de funcionários e seus identificadores. Para fins de simplicidade, a lista é serializada usando uma API Xstream.
  • O segundo método denomina-se updateEmployee(). Ele considera um objeto ActionScript serializado, denominado employee, como um arquivo XML.

Este exemplo mostra como criar o aplicativo do Flex e o aplicativo de portlet, e demonstra quão fácil é integrar os dois mundos: o Adobe Flex e o WebSphere Portal.

Siga estas etapas para construir um aplicativo de portlet:

  1. Abra o Rational Software Architect.
  2. Selecione File - New - Project.
  3. Na janela New Project, expanda a pasta Portal e selecione Portlet Project. Clique em Next.
  4. Na janela New Portlet Project, no campo Project name, digite FlexWebService. Nesta etapa, você cria um portlet básico que estende a classe GenericPortlet definida no Java Portlet Specification Versão 1.0 (JSR 168). Faça o seguinte:

    • Selecione WebSphere Portal v6.0 no campo Target Runtime.
    • Aceite as configurações padrão na seção EAR Membership.
    • Selecione JSR 168 Portlet no campo Portlet API.
    • Aceite as configurações padrão na seção Create a portlet.
    • Selecione a opção Show advance settings.
  5. Clique em Next.

    Figura 1. Definição do projeto do portlet
    Definição do projeto do portlet
  6. Na janela Project Facets, as seguintes configurações estão selecionadas como opções padrão:

    • Dynamic Web Module
    • Java
    • JSR 168 Portlets
    • JSR 168 Portlets on WebSphere Portal

    Clique em Next para aceitar tais opções. Veja a Figura 2.

    Figura 2. A janela Project Facets
    A janela Project Facets
  7. Na janela Portlet Settings exibida, as seguintes configurações padrão são selecionadas:

    • Em Content types and modes, o Content Type é text/html e o mode é view.
    • A opção Generate a custom portlet class está selecionada, o Package prefix padrão está definido como com.ibm.flexwebservice e o Class prefix padrão, como FlexWebServicePortlet.
    • Na seção locale-specific information, en está selecionado como padrão.

    Aceite as configurações padrão clicando em Avançar. Veja a Figura 3.

    Figura 3. A janela Portlet Settings
    A janela Portlet Settings
  8. Na janela Action and Preferences, desmarque todas as opções, como mostrado na Figura 4, e clique em Finish.

    Figura 4. A janela Action and Preferences
    A janela Action and Preferences
  9. Abra o projeto FlexWebService e clique com o botão direito do mouse na pasta WebContent. Crie uma nova pasta denominada movies. A estrutura de pastas do portlet FlexWebService se parece com a mostrada na Figura 5.

    Figura 5. A estrutura de pastas depois da inclusão da nova pasta movies
    A estrutura de pastas depois da inclusão da nova pasta movies
  10. Modifique a classe de portlet FlexWebServicePortlet, localizada dentro do pacote com.ibm.flexwebservice, para chamar o método FlexWebServicePortletView.jsp in doView(), como indicado na Listagem 1.
Listagem 1. FlexWebServicePortlet.java
Line:1    package com.ibm.flexwebservice;
Line:2    
Line:3    import java.io.*;
Line:4    import java.util.*;
Line:5    import javax.portlet.*;
Line:6    
Line:7    /**
Line:8     * A sample portlet based on GenericPortlet
Line:9     */
Line:10   public class FlexWebServicePortlet extends GenericPortlet {
Line:11   
Line:12   	public static final String JSP_FOLDER    = "/_FlexWebService/jsp/";    
                // JSP folder name
Line:13   
Line:14   	public static final String VIEW_JSP      = "FlexWebServicePortletView";  
                //JSP file name to be rendered on the view mode
Line:15   
Line:16   	/**
Line:17   	 * @see javax.portlet.Portlet#init()
Line:18   	 */
Line:19   	public void init() throws PortletException{
Line:20   		super.init();
Line:21   	}
Line:22   
Line:23   	/**
Line:24   	 * Serve up the <code>view</code> mode.
Line:25   	 * 
Line:26   	 * @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest, 
                    javax.portlet.RenderResponse)
Line:27   	 */
Line:28   	public void doView(RenderRequest request, RenderResponse response) 
                throws PortletException, IOException {
Line:29   		// Set the MIME type for the render response
Line:30   		response.setContentType(request.getResponseContentType());
Line:31   
Line:32   
Line:33   		// Invoke the JSP to render
Line:34   		PortletRequestDispatcher rd = getPortletContext().
                    getRequestDispatcher (getJspFilePath(request, VIEW_JSP));
Line:35   		rd.include(request,response);
Line:36   	}
Line:37   
Line:38   	/**
Line:39   	 * Returns JSP file path.
Line:40   	 * 
Line:41   	 * @param request Render request
Line:42   	 * @param jspFile JSP file name
Line:43   	 * @return JSP file path
Line:44   	 */
Line:45   	private static String getJspFilePath(RenderRequest request, 
                String jspFile) {
Line:46   		String markup = request.getProperty("wps.markup");
Line:47   		if( markup == null )
Line:48   			markup = getMarkup(request.getResponseContentType());
Line:49   		return JSP_FOLDER + markup + "/" + jspFile + "." 
                   + getJspExtension(markup);
Line:50   	}
Line:51   
Line:52   	/**
Line:53   	 * Convert MIME type to markup name.
Line:54   	 * 
Line:55   	 * @param contentType MIME type
Line:56   	 * @return Markup name
Line:57   	 */
Line:58   	private static String getMarkup(String contentType) {
Line:59   		if( "text/vnd.wap.wml".equals(contentType) )
Line:60   			return "wml";
Line:61           else
Line:62               return "html";
Line:63   	}
Line:64   
Line:65   	/**
Line:66   	 * Returns the file extension for the JSP file
Line:67   	 * 
Line:68   	 * @param markupName Markup name
Line:69   	 * @return JSP extension
Line:70   	 */
Line:71   	private static String getJspExtension(String markupName) {
Line:72   		return "jsp";
Line:73   	}
Line:74   
Line:75   }
  1. Dentro da pasta _FlexWebService/jsp/html, é possível encontrar FlexWebServicePortletView.jsp. Defina as tags OBJECT e EMBED, dentro da tag div, como mostrado nas linhas 17 a 34 do código ilustrado na Listagem 2.
Listagem 2. FlexWebServicePortletView.jsp
Line:1    <%@page session="true" contentType="text/html" 
             pageEncoding="ISO-8859-1" import="javax.portlet.*" %>
Line:2    <%@taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
Line:3    <portlet:defineObjects/>
Line:4    
Line:5    <style type="text/css">
Line:6    		#fxJavaScript { width: 90%; height: 500px; }
Line:7    		#html_controls {width: 15em; margin-top: 1em; padding: 1em;
Line:8    				color: white; border: solid 1px white;
Line:9    				font-family: Arial
Line:10   		}
Line:11   		body<#html_controls {	width: 13em;}
Line:12   		body {background-color: #869CA7;}
Line:13   </style>
Line:14   
Line:15   <div>
Line:16   
Line:17   		<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
Line:18   		  id="SampleUpdate" width="100%" height="500px"
Line:19   		 codebase="http://fpdownload.macromedia.com/get/flashplayer/
                      current/swflash.cab">
Line:20   			<param name="movie" value="<%=renderResponse.encodeURL
                        (renderRequest.getContextPath()+"/movies/
                        WebServiceFlex.swf")%>" />
Line:21   			<param name="quality" value="high" />
Line:22   			<param name="bgcolor" value="#869ca7" />
Line:23   			<param name="allowScriptAccess" value="sameDomain" />
Line:24   	<embed src="<%=renderResponse.encodeURL
                (renderRequest.getContextPath()+"/movies/WebServiceFlex.swf")%>"
Line:25   			quality="high" bgcolor="#869ca7"
Line:26   			width="100%" height="500px" name="SampleUpdate" 
                        align="middle"
Line:27   			play="true"
Line:28   			loop="false"
Line:29   			quality="high"
Line:30   			allowScriptAccess="sameDomain"
Line:31   			type="application/x-shockwave-flash"
Line:32   			pluginspage="http://www.adobe.com/go/getflashplayer">
Line:33   			</embed>
Line:34   		 </object>
Line:35   
Line:36   </div>

No Adobe Flex Builder, crie um novo projeto do Flex executando o procedimento a seguir:

  1. Na nova janela Flex Project, digite WebServiceFlex, no campo Project name, e clique em Finish.

    A estrutura de pastas do projeto agora se parece com a ilustrada na Figura 6.

    Figure 6. Estrutura do projeto do Flex
    Figure 6. Estrutura do projeto do Flex
  2. Modifique o arquivo WebServiceFlex.mxml de modo que ele se pareça como o código exibido na Listagem 3. As explicações linha por linha do código vêm logo após a Listagem 3.
Listagem 3. WebServiceFlex.mxml
Line:1    <?xml version="1.0" encoding="utf-8"?>
Line:2    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
             xmlns="*" layout="horizontal"
Line:3    creationComplete="onCreationComplete()">
Line:4    	
Line:5    
Line:6    	<mx:Script>
Line:7         <![CDATA[
Line:8            
Line:9    	   import mx.controls.Alert; 
Line:10   	   import mx.rpc.xml.SimpleXMLEncoder;
Line:11         import mx.utils.ObjectUtil;
Line:12         import mx.rpc.events.ResultEvent;
Line:13         import mx.rpc.events.FaultEvent;
Line:14   
Line:15   
Line:16    [Bindable]
Line:17   	private var myXML:XML;
Line:18   			
Line:19     private function onCreationComplete():void {
Line:20   		webService.getEmployees().send;
Line:21   	}
Line:22   				
Line:23   		private function callWS(evt:ResultEvent):void {
Line:24   		  var retVal:Object = evt.result;
Line:25   		  var newMessage:String = 
                      retVal as String;				
Line:26   		  myXML = new XML(newMessage);
Line:27   		  myGrid.dataProvider = myXML.Employee;	
Line:28   	}
Line:29   				
Line:30   				
Line:31   	     private function choosenItem(selectedItem:Object):void {
Line:32   	        formPanel.visible = false;
Line:33   			employeeObj.name      = selectedItem.name;
Line:34   			employeeObj.identifer = selectedItem.identifer;
Line:35   			formPanel.visible = true;
Line:36   			formPanel.setStyle("showEffect","fadeIn");
Line:37   			  }
Line:38   	          
Line:39   	      private function update(employeeObj:Object):void {
Line:40   	          var xml:XML = objectToXML(employeeObj);
Line:41   	          webService.updateEmployee(xml.toString());
Line:42   	          webService.getEmployees().send;
Line:43   	         }
Line:44   	          
Line:45   	      private function objectToXML(obj:Object):XML {
Line:46   	          var qName:QName = new QName("Employee");
Line:47   	          var xmlDocument:XMLDocument = new XMLDocument();
Line:48   	          var simpleXMLEncoder:SimpleXMLEncoder = 
                          new SimpleXMLEncoder(xmlDocument);
Line:49   	          var xmlNode:XMLNode = 
                          simpleXMLEncoder.encodeValue(obj, qName, xmlDocument);
Line:50   	          var xml:XML = new XML(xmlDocument.toString());
Line:51   	          // trace(xml.toXMLString());
Line:52   	          return xml;
Line:53   	        }
Line:54   
Line:55           ]]>
Line:56         </mx:Script>
Line:57   	
Line:58      <mx:Fade id="fadeIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
Line:59   	
Line:60      <mx:WebService id="webService"
Line:61              wsdl="http://localhost:8080/EmployeeWS/wsdl/EmployeesDB.wsdl">
Line:62           <mx:operation name="getEmployees" result="callWS(event);" />
Line:63       </mx:WebService>
Line:64   
Line:65   	<mx:Panel title="Employees" width="100%" height="100%">
Line:66   	<mx:DataGrid id="myGrid" labelField="{choosenItem(myGrid.selectedItem)}"  
                width="100%" height="50%"> 
Line:67   		<mx:columns>
Line:68   		<mx:DataGridColumn headerText="name" dataField="name" />
Line:69   		<mx:DataGridColumn headerText="identifer" dataField="identifer" />
Line:70       	</mx:columns>
Line:71   	</mx:DataGrid>
Line:72   	<mx:PieChart id="profitPie" dataProvider="{myXML.Employee}"  
                showDataTips="true" width="100%" height="50%">
Line:73         <mx:series>
Line:74           	<mx:PieSeries field="identifer" nameField="name" 
                        labelPosition="callout" />
Line:75         	  </mx:series>
Line:76       	</mx:PieChart>
Line:77     		
Line:78   	</mx:Panel>
Line:79   
Line:80   
Line:81   	<Employee id="employeeObj"
Line:82   		name="{employeeName.text}"
Line:83   		identifer="{identifer.text}"/>
Line:84   		
Line:85   		<mx:Panel id="formPanel" title="Form" width="100%" 
                    height="10%" visible="false" showEffect="{fadeIn}">	
Line:86   		<mx:Form width="100%"> 
Line:87   		  <mx:FormItem label="Name">
Line:88   			<mx:TextInput id="employeeName" 
                        text="{employeeObj.name}"/>
Line:89   			</mx:FormItem>
Line:90   			<mx:FormItem label="Identifer">
Line:91   				<mx:TextInput id="identifer" editable="false" 
                            text="{employeeObj.identifer}"/>
Line:92   			</mx:FormItem>
Line:93   		</mx:Form>
Line:94   
Line:95   		<mx:ControlBar>
Line:96   		<mx:Button buttonDown="true" label="Update" 
                    click="update(employeeObj);onCreationComplete();"/>
Line:97   		</mx:ControlBar>
Line:98   	</mx:Panel>
Line:99   	
Line:100  
Line:101  </mx:Application>

As linhas 2 a 3 da lista de código mostram a tag de aplicativo mx:Application. O Flex define um contêiner de aplicativo padrão que permite a inclusão de conteúdo no aplicativo sem que seja definido explicitamente outro contêiner. Especifique o layout como horizontal, o que significa que os dois painéis incluídos nesse filme são adjacentes entre si. Além disso, chame a função onCreationComplete() no evento CreationComplete. CreationComplete é o evento disparado no fim do ciclo de vida do componente, depois de ele ter sido integralmente criado junto com seus filhos, se for o caso.

As linhas 19 a 21 mostram a declaração da função onCreationComplete. Nessa função, você chama a função webservice acessando o método getEmployees().

Depois de chamar a função getEmployees(), a função callWS() é chamada com os resultados de retorno mostrados nas linhas 23 a 28. Nessa função, você cria um objeto XML e o liga ao atributo dataProvider da grade de dados.

As linhas 31 a 37 mostram a função label da grade de dados. A função chosenItem passa adiante toda a linha que está sendo selecionada na grade de dados. É possível ligar os valores dessa linha ao objeto employee. O objeto employee, por sua vez, está ligado aos campos do formulário. A linha 36 mostra como adicionar um efeito de esmaecimento ao formulário.

As linhas 39 a 43 ilustram a função update, que é chamada quando o botão Update é clicado. Nessa função, chamamos a função Web service updateEmployee().

As linhas 60 a 63 apresentam um componente WebService que chama um serviço da Web. Esse componente chama duas operações de serviço da Web, getEmployees() e updateEmployee().

As linhas 65 a 78 mostram a grade de dados e um gráfico de setores circulares incorporado a um painel intitulado "Employees." A grade de dados possui duas colunas, name e identifier. É possível usar a série de gráficos PieSeries com o controle PieChart para definir os dados do gráfico. Especifique identifier como uma propriedade do campo de modo que o gráfico saiba que valor usar para criar os setores circulares no tamanho apropriado.

As linhas 81 a 84 apresentam a inicialização de um objeto employee. Essa classe tem apenas dois campos, name e identifier.

As linhas 85 a 93 mostram o formulário que você pode usar para atualizar os dados do funcionário.

Observe que o efeito esmaecer (fadeIn) , no campo showEffect="{fadeIn}", mostra o fluxo de trabalho do aplicativo. A declaração e as propriedades do efeito esmaecer podem ser encontradas na linha 58. É possível tornar o formulário inicialmente invisível especificando false para a propriedade visible (como em visible="false"). Você pode tornar o identifier do campo não editável especificando false para a propriedade editable (como em editable="false").

As linhas 95 a 97 mostram o botão Update. Ao ser clicado, ele chama a função update e passa adiante o objeto employee, que está ligado aos campos do formulário, name e identifier.

  1. Em seguida, clique com o botão direito do mouse na pasta src e adicione uma nova classe ActionScript denominada Employee.as.

    Modifique Employee.as de modo que ele corresponda ao código exibido na Listagem 4.

Listagem 4. Employee.as
Line:1    package
Line:2    {
Line:3    	[Bindable] 
Line:4    
Line:5    	public class Employee
Line:6    	{
Line:7    		public function Employee()
Line:8    		{
Line:9    		}
Line:10   
Line:11   		public var name:String;
Line:12   
Line:13   		public var identifer:String;
Line:14   
Line:15   
Line:16   	}
Line:17   }
  1. Clique no botão Export Release Build para adicionar a pasta bin-release. Nessa pasta, é possível encontrar o filme WebServiceFlex.swf, que você necessita para o aplicativo do portlet.
  2. Mova o arquivo WebServiceFlex.swf para o projeto de portlet na pasta movies criada anteriormente.

É possível ver o código EmployeesDB.wsdl na Listagem 5.

Listagem 5. EmployeesDB.wsdl
Line:1    <?xml version="1.0" encoding="UTF-8"?>
Line:2    <wsdl:definitions targetNamespace="http://flex.ibm.com" 
             xmlns:apachesoap="http://xml.apache.org/xml-soap" 
             xmlns:impl="http://flex.ibm.com" xmlns:intf="http://flex.ibm.com" 
             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap=
             "http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd=
             "http://www.w3.org/2001/XMLSchema">
Line:3    <!--WSDL created by Apache Axis version: 1.4
Line:4    Built on Apr 22, 2006 (06:55:48 PDT)-->
Line:5     <wsdl:types>
Line:6      <schema elementFormDefault="qualified" targetNamespace=
               "http://flex.ibm.com" xmlns="http://www.w3.org/2001/XMLSchema">
Line:7       <element name="main">
Line:8        <complexType>
Line:9         <sequence>
Line:10         <element maxOccurs="unbounded" name="arg" type="xsd:string"/>
Line:11        </sequence>
Line:12       </complexType>
Line:13      </element>
Line:14      <element name="mainResponse">
Line:15       <complexType/>
Line:16      </element>
Line:17      <element name="getEmployees">
Line:18       <complexType/>
Line:19      </element>
Line:20      <element name="getEmployeesResponse">
Line:21       <complexType>
Line:22        <sequence>
Line:23         <element name="getEmployeesReturn" type="xsd:string"/>
Line:24        </sequence>
Line:25       </complexType>
Line:26      </element>
Line:27      <element name="updateEmployee">
Line:28       <complexType>
Line:29        <sequence>
Line:30         <element name="SubShadeXMLString" type="xsd:string"/>
Line:31        </sequence>
Line:32       </complexType>
Line:33      </element>
Line:34      <element name="updateEmployeeResponse">
Line:35       <complexType>
Line:36        <sequence>
Line:37         <element name="updateEmployeeReturn" type="xsd:string"/>
Line:38        </sequence>
Line:39       </complexType>
Line:40      </element>
Line:41      <element name="sendEmail">
Line:42       <complexType>
Line:43        <sequence>
Line:44         <element name="sendTO" type="xsd:string"/>
Line:45         <element name="subject" type="xsd:string"/>
Line:46         <element name="message" type="xsd:string"/>
Line:47        </sequence>
Line:48       </complexType>
Line:49      </element>
Line:50      <element name="sendEmailResponse">
Line:51       <complexType>
Line:52        <sequence>
Line:53         <element name="sendEmailReturn" type="xsd:string"/>
Line:54        </sequence>
Line:55       </complexType>
Line:56      </element>
Line:57     </schema>
Line:58    </wsdl:types>
Line:59   
Line:60      <wsdl:message name="sendEmailResponse">
Line:61   
Line:62         <wsdl:part element="impl:sendEmailResponse" name="parameters"/>
Line:63   
Line:64      </wsdl:message>
Line:65   
Line:66      <wsdl:message name="getEmployeesRequest">
Line:67   
Line:68         <wsdl:part element="impl:getEmployees" name="parameters"/>
Line:69   
Line:70      </wsdl:message>
Line:71   
Line:72      <wsdl:message name="getEmployeesResponse">
Line:73   
Line:74         <wsdl:part element="impl:getEmployeesResponse" name="parameters"/>
Line:75   
Line:76      </wsdl:message>
Line:77   
Line:78      <wsdl:message name="mainRequest">
Line:79   
Line:80         <wsdl:part element="impl:main" name="parameters"/>
Line:81   
Line:82      </wsdl:message>
Line:83   
Line:84      <wsdl:message name="mainResponse">
Line:85   
Line:86         <wsdl:part element="impl:mainResponse" name="parameters"/>
Line:87   
Line:88      </wsdl:message>
Line:89   
Line:90      <wsdl:message name="sendEmailRequest">
Line:91   
Line:92         <wsdl:part element="impl:sendEmail" name="parameters"/>
Line:93   
Line:94      </wsdl:message>
Line:95   
Line:96      <wsdl:message name="updateEmployeeResponse">
Line:97   
Line:98        <wsdl:part element="impl:updateEmployeeResponse" name="parameters"/>
Line:99   
Line:100     </wsdl:message>
Line:101  
Line:102     <wsdl:message name="updateEmployeeRequest">
Line:103  
Line:104        <wsdl:part element="impl:updateEmployee" name="parameters"/>
Line:105  
Line:106     </wsdl:message>
Line:107  
Line:108     <wsdl:portType name="EmployeesDB">
Line:109  
Line:110        <wsdl:operation name="main">
Line:111  
Line:112           <wsdl:input message="impl:mainRequest" name="mainRequest"/>
Line:113  
Line:114           <wsdl:output message="impl:mainResponse" name="mainResponse"/>
Line:115  
Line:116        </wsdl:operation>
Line:117  
Line:118        <wsdl:operation name="getEmployees">
Line:119  
Line:120           <wsdl:input message="impl:getEmployeesRequest" 
                       name="getEmployeesRequest"/>
Line:121  
Line:122           <wsdl:output message="impl:getEmployeesResponse" 
                       name="getEmployeesResponse"/>
Line:123  
Line:124        </wsdl:operation>
Line:125  
Line:126        <wsdl:operation name="updateEmployee">
Line:127  
Line:128           <wsdl:input message="impl:updateEmployeeRequest" 
                       name="updateEmployeeRequest"/>
Line:129  
Line:130           <wsdl:output message="impl:updateEmployeeResponse" 
                       name="updateEmployeeResponse"/>
Line:131  
Line:132        </wsdl:operation>
Line:133  
Line:134        <wsdl:operation name="sendEmail">
Line:135  
Line:136           <wsdl:input message="impl:sendEmailRequest" 
                       name="sendEmailRequest"/>
Line:137  
Line:138           <wsdl:output message="impl:sendEmailResponse" 
                       name="sendEmailResponse"/>
Line:139  
Line:140        </wsdl:operation>
Line:141  
Line:142     </wsdl:portType>
Line:143  
Line:144     <wsdl:binding name="EmployeesDBSoapBinding" type="impl:EmployeesDB">
Line:145  
Line:146        <wsdlsoap:binding style="document" 
                    transport="http://schemas.xmlsoap.org/soap/http"/>
Line:147  
Line:148        <wsdl:operation name="main">
Line:149  
Line:150           <wsdlsoap:operation soapAction=""/>
Line:151  
Line:152           <wsdl:input name="mainRequest">
Line:153  
Line:154              <wsdlsoap:body use="literal"/>
Line:155  
Line:156           </wsdl:input>
Line:157  
Line:158           <wsdl:output name="mainResponse">
Line:159  
Line:160              <wsdlsoap:body use="literal"/>
Line:161  
Line:162           </wsdl:output>
Line:163  
Line:164        </wsdl:operation>
Line:165  
Line:166        <wsdl:operation name="getEmployees">
Line:167  
Line:168           <wsdlsoap:operation soapAction=""/>
Line:169  
Line:170           <wsdl:input name="getEmployeesRequest">
Line:171  
Line:172              <wsdlsoap:body use="literal"/>
Line:173  
Line:174           </wsdl:input>
Line:175  
Line:176           <wsdl:output name="getEmployeesResponse">
Line:177  
Line:178              <wsdlsoap:body use="literal"/>
Line:179  
Line:180           </wsdl:output>
Line:181  
Line:182        </wsdl:operation>
Line:183  
Line:184        <wsdl:operation name="updateEmployee">
Line:185  
Line:186           <wsdlsoap:operation soapAction=""/>
Line:187  
Line:188           <wsdl:input name="updateEmployeeRequest">
Line:189  
Line:190              <wsdlsoap:body use="literal"/>
Line:191  
Line:192           </wsdl:input>
Line:193  
Line:194           <wsdl:output name="updateEmployeeResponse">
Line:195  
Line:196              <wsdlsoap:body use="literal"/>
Line:197  
Line:198           </wsdl:output>
Line:199  
Line:200        </wsdl:operation>
Line:201  
Line:202        <wsdl:operation name="sendEmail">
Line:203  
Line:204           <wsdlsoap:operation soapAction=""/>
Line:205  
Line:206           <wsdl:input name="sendEmailRequest">
Line:207  
Line:208              <wsdlsoap:body use="literal"/>
Line:209  
Line:210           </wsdl:input>
Line:211  
Line:212           <wsdl:output name="sendEmailResponse">
Line:213  
Line:214              <wsdlsoap:body use="literal"/>
Line:215  
Line:216           </wsdl:output>
Line:217  
Line:218        </wsdl:operation>
Line:219  
Line:220     </wsdl:binding>
Line:221  
Line:222     <wsdl:service name="EmployeesDBService">
Line:223  
Line:224       <wsdl:port binding="impl:EmployeesDBSoapBinding" name="EmployeesDB">
Line:225  
Line:226           <wsdlsoap:address location=
                        "http://localhost:8080/EmployeeWS/services/EmployeesDB"/>
Line:227  
Line:228        </wsdl:port>
Line:229  
Line:230     </wsdl:service>
Line:231  
Line:232  </wsdl:definitions>

O código por trás do arquivo WSDL é simples. O arquivo EmployeesDB.java tem dois métodos:

  • Um deles se chama getEmployees(), que se conecta ao banco de dados e recupera todos os valores na tabela employees. Ele cria um objeto list employee e preenche seus campos, name e identifier. Veja a Figura 7.

    Figura 7. Tabela employee no banco de dados
    Tabela employee no banco de dados
  • O segundo método, denominado updateEmployee(), toma como entrada uma cadeia de caractere no formato XML e a decodifica em um bean “Employee”. Em seguida, atualiza o nome do funcionário na tabela employee usando o campo identifier, que é a chave primária para essa tabela.

Para ver o código de origem desse serviço da Web, consulte o Source code of “EmployeesDB webservices”, na seção Downloads, no final deste arquivo.

A última etapa é implementar o aplicativo do portlet no seu servidor WebSphere Portal. O portlet se parece àquele exibido na Figura 8.

Figura 8. Portlet FlexWebService como ele aparece no navegador Internet Explorer
Portlet FlexWebService como ele aparece no navegador Internet Explorer

Usando o JSON

O JavaScript Object Notation, comumente chamado JSON, é um formato leve de intercâmbio de dados. É fácil para humanos ler e escrever, e é fácil para computadores analisar e gerar. O JSON se baseia em um subconjunto da linguagem de programação JavaScript (Standard ECMA-262, Terceira Edição, dezembro de 1999). É um formato de texto completamente independente da linguagem, mas que usa convenções familiares para os programadores da família C (incluindo C, C++, C#, Java, JavaScript, Perl, Python, etc.). Essas propriedades transformam o JSON em uma linguagem de intercâmbio de dados ideal.

O JSON foi construído sobre duas estruturas:

  • Uma coleção de pares nome-valor. Em diversas linguagens, essa coleção é realizada como um objeto, registro, estrutura, dicionário, tabela hash, lista codificada ou array associativa.
  • Uma lista ordenada de valores. Na maioria das linguagens, essa lista é concebida como array, vetor, lista ou sequência.

Essas são estruturas de dados universais. Virtualmente, todas as linguagens de programação modernas as suportam de uma forma ou outra. Portanto, faz sentido que um formato de dados que seja intercambiável entre linguagens de programação também se baseie em tais estruturas.

O Ajax é uma tecnologia de desenvolvimento da Web que agiliza as respostas do servidor, permitindo que os scripts do lado do cliente recuperem apenas os dados necessários a partir do servidor, sem recuperar uma página da Web completa em cada pedido, uma abordagem que pode minimizar os dados transferidos do servidor.

Esses pedidos normalmente recuperam as respostas formatadas em XML, as quais são, por sua vez, analisadas no código JavaScript para renderizar os resultados, o que complica o código JavaScript code.

A ideia do JSON é tornar a resposta uma estrutura de dados específica que possa ser facilmente analisada pelo código JavaScript.

O JSON apresenta diversas vantagens:

  • É um formato leve de intercâmbio de dados.
  • É fácil de ser lido e escrito pelos humanos.
  • É fácil de ser analisado e gerado pelos computadores.
  • Pode ser analisado trivialmente usando o procedimento eval() no JavaScript.
  • Suporta ActionScript, C, C#, ColdFusion, E, Java, JavaScript, ML, Objective CAML, Perl, PHP, Python, Rebol, Ruby e Lua.

Executando Adobe Flex por meio de objetos JSON em um portlet do WebSphere Portal

Neste exemplo, é possível aprender a como executar um aplicativo. O aplicativo do Flex faz chamadas em um objeto JSON registrado no servlet de backend, no aplicativo do portal. O servlet JSON recupera os objetos do banco de dados. O aplicativo do Flex também fornece um formulário para atualização da grade de dados. Na submissão do formulário, uma função de atualização no servlet JSON é chamada e sincroniza o banco de dados concordemente.

Siga estas etapas para construir um aplicativo de portlet:

  1. Abra o Rational Software Architect.
  2. Selecione File - New - Project.
  3. Na janela New Project, expanda a pasta Portal e selecione Portlet Project. Clique em Next.
  4. Na janela New Portlet Project, execute um dos seguintes procedimentos:

    • No campo Project name, digite FlexJSONPortlet. Desse modo, você cria um portlet básico que estende a classe GenericPortlet definida no Java Portlet Specification Versão 1.0 (JSR 168).
    • Selecione WebSphere Portal V6.0 como Target RunTime.
    • Aceite as configurações padrão para EAR Membership.
    • Selecione JSR 168 Portlet no campo Portlet API.
    • Aceite as configurações padrão na seção Create a portlet.
    • Desmarque a opção Show advanced settings.

    Clique em Next.

    Figura 9. Definição do projeto do portlet
    Definição do projeto do portlet
  5. Na janela Project Facets, as seguintes configurações estão selecionadas como opções padrão:

    • Dynamic Web Module
    • Java
    • JSR 168 Portlets
    • JSR 168 Portlets on WebSphere Portal

    Clique em Next para aceitar as opções padrão. Veja a Figura 10.

    Figura 10. Project Facets
    Project Facets
  6. Na janela Portlet Settings, as seguintes configurações padrão estão selecionadas:

    • Em Content types and modes, o Content Type é text/html e o mode é view.
    • A opção Generate a custom portlet class está selecionada, o Package prefix padrão está definido como com.ibm.flexwebservice e o Class prefix padrão, como FlexWebServicePortlet.
    • Na seção Locale-specific information, en está selecionado como padrão.

    Aceite as configurações padrão clicando em Avançar. Veja a Figura 11.

    Figura 11. A janela Portlet Settings
    A janela Portlet Settings
  7. Na janela Action and Preferences, desmarque todas as opções e clique em Finish.
  8. Abra o projeto FlexJSONPortlet e clique com o botão direito do mouse na pasta WebContent. Inclua uma nova pasta chamada movies. A estrutura de pastas do portlet FlexWebService se parece com a mostrada na Figura 12.

    Figura 12. Estrutura de pastas depois da inclusão da pasta "movies"
    Estrutura de pastas depois da inclusão da pasta
  9. Em seguida, modifique a classe do portlet FlexJSONPortlet localizada no pacote com.ibm.flexjsonportlet, para chamar o FlexJSONPortletView.jsp no método doView() como no código na Listagem 6.
Listagem 6. FlexJSONPortlet.java
Line:1    package com.ibm.flexjsonportlet;
Line:2    
Line:3    import java.io.*;
Line:4    import javax.portlet.*;
Line:5    
Line:6    public class FlexJSONPortlet extends GenericPortlet {
Line:7    	
Line:8    	public static final String JSP_FOLDER    = "/_FlexJSONPortlet/jsp/";   
                // JSP folder name
Line:9    	public static final String VIEW_JSP      = "FlexJSONPortletView";         
                // JSP file name to be rendered on the view mode
Line:10   
Line:11   	public void doView(RenderRequest request, RenderResponse response) 
                throws PortletException, IOException {
Line:12   		// Set the MIME type for the render response
Line:13   		response.setContentType(request.getResponseContentType());
Line:14   
Line:15   		// Invoke the JSP to render
Line:16   		PortletRequestDispatcher rd =  
                    getPortletContext().getRequestDispatcher
                    (getJspFilePath(request, VIEW_JSP));
Line:17   		rd.include(request,response);
Line:18   	}
Line:19   
Line:20   	private static String getJspFilePath(RenderRequest request, 
                String jspFile) {
Line:21   		String markup = request.getProperty("wps.markup");
Line:22   		if( markup == null )
Line:23   			markup = getMarkup(request.getResponseContentType());
Line:24   		return JSP_FOLDER + markup + "/" + jspFile + "." 
                    + getJspExtension(markup);
Line:25   	}
Line:26   
Line:27   
Line:28   	private static String getMarkup(String contentType) {
Line:29   		if( "text/vnd.wap.wml".equals(contentType) )
Line:30   			return "wml";
Line:31           else
Line:32               return "html";
Line:33   	}
Line:34   
Line:35   	private static String getJspExtension(String markupName) {
Line:36   		return "jsp";
Line:37   	}
Line:38   
Line:39   }
  1. Na pasta _FlexJSONPortlet/jsp/html, você encontra FlexJSONPortletView.jsp. Defina as tags OBJECT e EMBED, dentro da tag div, como mostrado nas linhas 26 a 43. Nas linhas 18 a 21, há um Javascript getURL que é chamado a partir do aplicativo do Flex. A função JS retorna a URL para o servlet JSON. Veja a Listagem 7.
Listagem 7. FlexJSONPortletView.jsp
Line:1    <%@page session="false" contentType="text/html" pageEncoding="ISO-8859-1" 
             import="java.util.*,javax.portlet.*,com.ibm.flexjsonportlet.*" %>
Line:2    <%@taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
Line:3    <portlet:defineObjects/>
Line:4    
Line:5    
Line:6    <style type="text/css">
Line:7    		#fxJavaScript { width: 90%; height: 500px; }
Line:8    		#html_controls {width: 15em; margin-top: 1em; padding: 1em;
Line:9    				color: white; border: solid 1px white;
Line:10   				font-family: Arial
Line:11   		}
Line:12   		body>#html_controls {	width: 13em;}
Line:13   		body {background-color: #869CA7;}
Line:14   </style>
Line:15   
Line:16   
Line:17   <script language="JavaScript">
Line:18   		function getURL() {		   
Line:19   		    var urlString = "<%=renderResponse.encodeURL
                        (renderRequest.getContextPath()+"/JSONServlet")%>";
Line:20   		    return urlString;	
Line:21   		}		
Line:22   </script>
Line:23   
Line:24   <div>
Line:25         
Line:26   	<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
Line:27   			id="jsonrpcserializing" width="100%" height="500px"
Line:28   			codebase="http://fpdownload.macromedia.com/get/
                        flashplayer/current/swflash.cab">
Line:29   			<param name="movie" value="<%=renderResponse.encodeURL
                        (renderRequest.getContextPath()+
                        "/movies/jsonrpcserializing.swf")%>" />
Line:30   			<param name="quality" value="high" />
Line:31   			<param name="bgcolor" value="#869ca7" />
Line:32   			<param name="allowScriptAccess" value="sameDomain" />
Line:33   	<embed src="<%=renderResponse.encodeURL(renderRequest.getContextPath()+
                "/movies/jsonrpcserializing.swf")%>"
Line:34   			quality="high" bgcolor="#869ca7"
Line:35   			width="100%" height="500px" name="jsonrpcserializing" 
                        align="middle"
Line:36   				play="true"
Line:37   				loop="false"
Line:38   				quality="high"
Line:39   				allowScriptAccess="sameDomain"
Line:40   				type="application/x-shockwave-flash"
Line:41   				pluginspage=
                            "http://www.adobe.com/go/getflashplayer">
Line:42   			</embed>
Line:43   	</object>
Line:44   
Line:45   </div>

O JSONServlet.java apresenta dois métodos: doGet() e updateEmployee().

  • O método doGet() consulta um banco de dados de backend usando a classe JDBC, cria o JSONObject e o concatena com uma JSONArray.
  • O método updateEmployee() procura os parâmetros name e identifier no pedido HTTP atual a fim de atualizar o banco de dados.

Consulte a Listagem 8.

Listagem 8. JSONServlet.java
Line:1    package com.ibm.flexjsonportlet.json;
Line:2    
Line:3    import java.io.*;
Line:4    import java.sql.Connection;
Line:5    import java.sql.DriverManager;
Line:6    import java.sql.ResultSet;
Line:7    import java.sql.Statement;
Line:8    import javax.servlet.*;
Line:9    import javax.servlet.http.*;
Line:10   import org.json.JSONArray;
Line:11   import org.json.JSONObject;
Line:12   
Line:13   
Line:14   
Line:15   
Line:16   public class JSONServlet extends  HttpServlet{
Line:17   	  
Line:18       String url = "jdbc:mysql://localhost:3306/";
Line:19       String dbName = "flex";
Line:20       String driver = "com.mysql.jdbc.Driver";
Line:21       String userName = "root"; 
Line:22       String password = "admin";
Line:23       Connection conn = null;
Line:24       
Line:25       
Line:26     public void init(ServletConfig config) throws ServletException {
Line:27           super.init(config);
Line:28           try {
Line:29   		    Class.forName(driver).newInstance();
Line:30   			conn = DriverManager.getConnection(url+dbName,
                        userName,password);
Line:31   			System.out.println("Connected to the database");
Line:32   			    
Line:33           }catch (Exception e) {
Line:34   				e.printStackTrace();
Line:35   			}
Line:36           
Line:37     }
Line:38   
Line:39     public void doGet(HttpServletRequest request,HttpServletResponse response)
Line:40      throws ServletException,IOException{
Line:41   	  	
Line:42   	  	
Line:43           
Line:44           updateEmployee(request);
Line:45           JSONArray array=new JSONArray();
Line:46   	    try {
Line:47   	   
Line:48   		    Statement st = conn.createStatement();
Line:49   		    String query = "select * from employee";
Line:50   	        ResultSet rs = st.executeQuery(query);
Line:51   	        while (rs.next()){
Line:52   	        	JSONObject obj=new JSONObject();
Line:53   	        	obj.put("name", rs.getString("name")!=
                            null?rs.getString("name"):"");
Line:54   	        	obj.put("identifer", rs.getString("identifer")!=
                            null?rs.getString("identifer"):""); 
Line:55   	        	array.put(obj);
Line:56   	        }
Line:57   	        rs.close();
Line:58   			st.close();
Line:59   	        System.out.println("query excuted successfully!");
Line:60   	    } catch (Exception e) {
Line:61   		      e.printStackTrace();
Line:62   	    }
Line:63   	  
Line:64   	  
Line:65   	  PrintWriter out = new PrintWriter(response.getWriter(),true);
Line:66   	  out.println(array);
Line:67      
Line:68     }
Line:69     
Line:70   	public void updateEmployee(HttpServletRequest request) {
Line:71   	 try{
Line:72   		String name=request.getParameter("name");
Line:73   		String identifer=request.getParameter("identifer");
Line:74   		if (name!=null && identifer!=null){
Line:75   			Statement st = conn.createStatement();
Line:76   			st.executeUpdate ("update employee set name = 
                        '"+name+"', " +
Line:77   				"identifer = "+identifer+
Line:78   				"where identifer = "+identifer+" ");
Line:79   			 st.close ();
Line:80   			 System.out.println(name +" - "+ identifer);
Line:81   		   }
Line:82   		}catch(Exception ex){ex.printStackTrace();}
Line:83   		
Line:84   	}
Line:85   }
  1. Modifique o arquivo web.xml, como mostrado na Listagem 9.
Listagem 9. web.xml
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=
"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>
	FlexJSONPortlet</display-name>
	<servlet>
		<description>
		</description>
		<display-name>
		JSONServlet</display-name>
		<servlet-name>JSONServlet</servlet-name>
		<servlet-class>
		com.ibm.flexjsonportlet.json.JSONServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>JSONServlet</servlet-name>
		<url-pattern>/JSONServlet</url-pattern>
	</servlet-mapping>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
	<jsp-config>
		<taglib>
			<taglib-uri>http://java.sun.com/portlet</taglib-uri>
			<taglib-location>/WEB-INF/tld/std-portlet.tld</taglib-location>
		</taglib>
	</jsp-config>
</web-app>
  1. Abra o Adobe Flex Builder e crie um novo projeto do Flex.
    Mbr/>

    Na janela New Flex Project, digite jsonrpcserializing no campo Project name, aceite todas as configurações padrão e clique em Finish.

    A estrutura de pastas do projeto agora se parece com a ilustrada na Figura 13.

    Figura 13. Estrutura de projetos do Flex
    Estrutura de projetos do Flex
  2. Modifique o arquivo jsonrpcserializing.mxml, como mostrado na Listagem 10. As explicações linha por linha do código se encontram depois da Listagem 10.
Listagem 10. jsonrpcserializing.mxml
Line:1    <?xml version="1.0" encoding="utf-8"?>
Line:2    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" 
             layout="horizontal"
Line:3    	creationComplete="onCreationComplete()">
Line:4    	
Line:5    	<mx:HTTPService id="service" resultFormat="text"
Line:6    			result="onLoad(event)" />
Line:7    
Line:8    
Line:9    		<mx:Script>
Line:10   	       <![CDATA[
Line:11   	        
Line:12   		import mx.rpc.events.*;
Line:13   		import com.adobe.serialization.json.JSON;
Line:14   		import mx.rpc.events.ResultEvent;
Line:15   		import mx.controls.Alert;
Line:16   		import mx.collections.ArrayCollection;
Line:17   		import flash.external.ExternalInterface;
Line:18   	
Line:19   		private function onCreationComplete():void {
Line:20   			if (!ExternalInterface.available)
Line:21   				 Alert.show( "No ExternalInterface available 
                            for container" );
Line:22   			callJavaScript();
Line:23   					
Line:24   			}
Line:25   				
Line:26   		 private function callJavaScript():void {
Line:27   			if (!ExternalInterface.available) 
Line:28   			return;
Line:29   				var retVal:Object = ExternalInterface.call
                            ("getURL","");
Line:30   				var urlString:String = retVal as String;
Line:31   				service.url = urlString;
Line:32   				service.send();
Line:33   			}
Line:34   				
Line:35   		private function onLoad(event:ResultEvent):void {
Line:36   		//get the raw JSON data and cast to String
Line:37   		var rawData:String = String(event.result);
Line:38   	
Line:39   		//decode the data to ActionScript using the JSON API
Line:40   		//in this case, the JSON data is a serialize Array of Objects.
Line:41   		var arr:Array = (JSON.decode(rawData) as Array);
Line:42   	
Line:43   		//create a new ArrayCollection passing the de-serialized Array
Line:44   		//ArrayCollections work better as DataProviders, as they can
Line:45   		//be watched for changes.
Line:46   		var dp:ArrayCollection = new ArrayCollection(arr);
Line:47   	
Line:48   		//pass the ArrayCollection to the DataGrid as its dataProvider.
Line:49   		myGrid.dataProvider = dp;
Line:50   		profitPie.dataProvider = dp;
Line:51   		}
Line:52   				
Line:53   		private function choosenItem(selectedItem:Object):void {
Line:54   		        	            formPanel.visible  =  false;
Line:55   		employeeObj.name      = selectedItem.name;
Line:56   		employeeObj.identifer = selectedItem.identifer;
Line:57   		formPanel.visible 	  = true;
Line:58   		formPanel.setStyle("showEffect","fadeIn");
Line:59   		 }
Line:60   				  
Line:61   			 private function submitForm():void {
Line:62   			   //Alert.show(employeeObj.name);
Line:63   			   service.send(employeeObj);
Line:64   			}
Line:65   	
Line:66   	        ]]>
Line:67   	    </mx:Script>
Line:68   
Line:69   	    <mx:Fade id="fadeIn" duration="1000" alphaFrom="0.0" 
                    alphaTo="1.0"/>
Line:70   	    
Line:71   		<mx:Panel title="Employees" width="100%" height="100%">
Line:72   		<mx:DataGrid id="myGrid" labelField=
                    "{choosenItem(myGrid.selectedItem)}" width="100%" height="50%"> 
Line:73   				<mx:columns>
Line:74   				<mx:DataGridColumn headerText="name" 
                            dataField="name" />
Line:75   				<mx:DataGridColumn headerText="identifer" 
                            dataField="identifer" />
Line:76   	    		</mx:columns>
Line:77   		</mx:DataGrid>
Line:78   		<mx:PieChart id="profitPie"  showDataTips="true" width="100%" 
                      height="50%">
Line:79   	      	<mx:series>
Line:80   	        	<mx:PieSeries field="identifer" nameField="name" 
                                 labelPosition="callout" />
Line:81   	      		</mx:series>
Line:82   	    	</mx:PieChart>
Line:83   		</mx:Panel>
Line:84   		
Line:85   		
Line:86   		<mx:Model id="employeeObj">
Line:87   			<root>
Line:88   				<name>{employeeName.text}</name>
Line:89   				<identifer>{identifer.text}</identifer>
Line:90   			</root>
Line:91   		</mx:Model>
Line:92   		
Line:93   		<mx:Panel id="formPanel" title="Form" width="100%" height="10%" 
                    visible="false" showEffect="{fadeIn}">	
Line:94   			<mx:Form width="100%"> 
Line:95   				<mx:FormItem label="Name">
Line:96   					<mx:TextInput id="employeeName" 
                                text="{employeeObj.name}"/>
Line:97   				</mx:FormItem>
Line:98   				<mx:FormItem label="Identifer">
Line:99   				<mx:TextInput id="identifer" editable="false" 
                            text="{employeeObj.identifer}"/>
Line:100  				</mx:FormItem>
Line:101  			</mx:Form>
Line:102  	
Line:103  			<mx:ControlBar>
Line:104  				<mx:Button buttonDown="true" label="Update" 
                            click="submitForm()"/>
Line:105  			</mx:ControlBar>
Line:106  		</mx:Panel>
Line:107  
Line:108  </mx:Application>

As linhas 2 e 3 mostram a tag de aplicativo mx:Application. O Flex define um contêiner de aplicativo padrão que permite iniciar a inclusão de conteúdo no aplicativo sem a definição explícita de outro contêiner. É possível especificar o layout como horizontal, o que significa que os dois painéis incluídos nesse filme são adjacentes entre si. Ademais, você pode chamar a função onCreationComplete() no evento CreationComplete. CreationComplete é o evento disparado no fim do ciclo de vida do componente, depois de ele ter sido criado junto com seus filhos, se for o caso.

As linhas 19 a 24 contêm a declaração da função onCreationComplete, na qual você procura a instância do ExternalInterface que está sendo declarada e chama função callJavaScript().

As linhas 26 a 33 chamam a função sequencial getURL() que retorna a URL do servlet JSON. Além disso, ela define o atributo URL para o serviço HTTP e, por fim, chama o serviço usando o método send().

As linhas 35 a 51 mostram a função onLoad() registrada para o HTTPservice. Essa função é chamada como resultado da chamada do serviço HTTP. A função onLoad() captura os dados JSON brutos e os distribui para String, decodifica os dados para ActionScript usando a API JSON (nesse caso, os dados JSON são uma array de objetos serializada, e cria uma nova ArrayCollection informando a Array desserializada. A função ArrayCollection funciona melhor do que os DataProviders, pois permite o monitoramento das alterações. Finalmente, ela passa a ArrayCollection para o DataGrid como seu dataProvider.

As linhas 53 a 60 mostram a função label da grade de dados. A função chosenItem passa adiante toda a linha que está sendo selecionada na grade de dados. Você liga os valores dessa linha ao modelo employee.

O objeto employee, por sua vez, está ligado aos campos do formulário. A linha 58 mostra como adicionar um efeito de esmaecimento ao formulário.

As linhas 61 a 64 mostram a função submitForm(). Essa função é chamada quando o botão Update é clicado.

As linhas 71 a 83 mostram uma grade de dados e um gráfico de setores circulares dentro de um painel intitulado Employees. A grade de dados possui duas colunas, name e identifier. Use a série de gráficos PieSeries com o controle PieChart para definir os dados do gráfico. Especifique identifier como uma propriedade do campo de modo que o gráfico saiba que valor usar para criar os setores circulares no tamanho apropriado.

As linhas 94 a 101 mostram o formulário usado para atualizar os dados do funcionário. Observe o efeito esmaecer ("fadeIn") , no campo showEffect="{fadeIn}", que mostra o fluxo de trabalho do aplicativo. É possível localizar a declaração e as propriedades do efeito esmaecer na linha 69.

As linhas 103 a 106 mostram o botão Update. Ao ser clicado, ele chama a função submitForm() e passa adiante o modelo employee, que está ligado aos campos do formulário, name e identifier.

  1. Clique no botão Export Release Build Export Release Build button para adicionar a pasta bin-release onde se encontra o arquivo de filme jsonrpcserialization.swf, que precisa ser movido para o projeto do portlet, na pasta movies criada anteriormente. Veja a Figura 14.

    Figura 14. Estrutura de pastas do projeto jsonrpcserialization
    Estrutura de pastas do projeto jsonrpcserialization
  2. Retorne ao projeto do portal; basta executá-lo. A aparência do portlet está ilustrada na Figure 15.

    Figura 15. Portlet FlexJSON como exibido no navegador Internet Explorer
    Portlet FlexJSON como exibido no navegador Internet Explorer

Conclusão

O Adobe Flex é uma nova ferramenta que pode distribuir aplicativos da Internet elaborados. O Adobe Flex é uma solução cliente que pode ser aplicada em diversos navegadores e plataformas. O Adobe Flex proporciona a um aplicativo de portal muitas vantagens, como atualização das informações em uma página do navegador sem a necessidade de atualizar toda a página. No ambiente do portal, atualizar uma página inteira para disponibilizar uma funcionalidade pode ser uma operação dispendiosa em termos de recursos de rede e desempenho geral. O Adobe Flex fornece um meio, através do cliente proxy SOA e do adaptador JSON incorporados, para disponibilizar funcionalidades elaboradas dentro de uma estrutura de portal. O artigo mostrou um exemplo linha por linha de como integrar o Adobe Flex no WebSphere Portal. É possível usar o Flex para renderizar a interface com o usuário dos portlets, superar as limitações do HTML e aprimorar grandemente a experiência do usuário dentro do portal.


Downloads

DescriçãoNomeTamanho
Source code for EmployeesDB Web servicesEmployeeWS.zip2578KB
Project attachment for FlexWebService portletFlexWebServicePortal.zip721KB
Source code for the WebServiceFlex applicationWebServiceFlex.zip14KB
Source code for jsonrpcserializationjsonrpcserializing.zip1332KB
Source code for FlexJsonPortletFlexJSONPortlet.zip1154KB

Recursos

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 acessar o developerWorks, um perfil será criado para você. Informações do seu perfil (tais como: nome, país / região, e empresa) estarão disponíveis ao público, que poderá acompanhar qualquer conteúdo que você publicar. Seu perfil no developerWorks pode ser atualizado 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=451237
ArticleTitle=Integrando o Adobe Flex com o IBM WebSphere Portal
publish-date=11302009