Skip to content

6. Client Flex per il servizio di appuntamenti JEE

Presentiamo ora due client Flex per il servizio web JEE per gli appuntamenti. L'IDE utilizzato è Flex Builder 3. Una versione demo di questo prodotto può essere scaricata dall'URL [https://www.adobe.com/cfusion/tdrc/index.cfm?loc=fr_fr&product=flex]. Flex Builder 3 è un IDE basato su Eclipse. Inoltre, per eseguire il client Flex, utilizziamo un server web Apache fornito dallo strumento Wamp [http://www.wampserver.com/]. È compatibile qualsiasi server Apache. Il browser che visualizza il client Flex deve avere installato Flash Player versione 9 o superiore.

Le applicazioni Flex sono uniche in quanto vengono eseguite all'interno del plugin Flash Player del browser. Sotto questo aspetto, sono simili alle applicazioni Ajax, che incorporano script JavaScript nelle pagine inviate al browser, che vengono poi eseguiti all'interno del browser. Un'applicazione Flex non è un'applicazione web nel senso comune del termine: è un'applicazione client per servizi forniti da server web. Sotto questo aspetto, è analoga a un'applicazione desktop che funge da client per questi stessi servizi. Si differenzia, tuttavia, sotto un aspetto: viene inizialmente scaricata da un server web in un browser dotato del plugin Flash Player in grado di eseguirla.

Come un'applicazione desktop, un'applicazione Flex è costituita principalmente da due elementi:

  • un livello di presentazione: le viste visualizzate nel browser. Queste viste offrono la stessa ricchezza delle finestre delle applicazioni desktop. Una vista è descritta utilizzando un linguaggio di marcatura chiamato MXML.
  • un componente di codice che gestisce principalmente gli eventi attivati dalle azioni dell'utente sulla vista. Questo codice può essere scritto anche in MXML o in un linguaggio orientato agli oggetti chiamato ActionScript. È necessario distinguere due tipi di eventi:
  • eventi che richiedono la comunicazione con il server web: popolare un elenco con dati forniti da un'applicazione web, inviare dati di un modulo al server, ecc. Flex fornisce una serie di metodi per comunicare con il server in modo trasparente per lo sviluppatore. Questi metodi sono asincroni per impostazione predefinita: l'utente può continuare a interagire con la vista mentre la richiesta al server è in corso.
  • eventi che modificano la vista visualizzata senza scambiare dati con il server, come trascinare un elemento da una struttura ad albero e rilasciarlo in un elenco. Questo tipo di evento viene gestito interamente a livello locale all'interno del browser.

Un'applicazione Flex viene spesso eseguita come segue:

  • in [1], viene richiesta una pagina HTML
  • In [2], viene inviata. Essa include un file binario SWF (ShockWave Flash) contenente l’intera applicazione Flex: tutte le viste e il loro codice di gestione degli eventi. Questo file verrà eseguito dal plugin Flash Player del browser.
  • Il client Flex viene eseguito localmente nel browser, tranne quando necessita di dati esterni. In tal caso, li richiede al server [3]. Li riceve in [4] in vari formati: XML o binario. L'applicazione interrogata sul server web può essere scritta in qualsiasi linguaggio. Conta solo il formato della risposta.

Abbiamo descritto l'architettura di esecuzione di un'applicazione Flex in modo che il lettore possa comprendere chiaramente la differenza tra questa e quella di un'applicazione web tradizionale, senza Ajax, come l'applicazione Asp.Net descritta in precedenza. In quest'ultima, il browser è passivo: si limita a visualizzare pagine HTML costruite sul server web, che le invia al browser.

Nelle sezioni seguenti, forniamo due esempi di client Flex al solo scopo di dimostrare la diversità dei client per un servizio web. Poiché l'autore è egli stesso un principiante di Flex, alcuni punti potrebbero non essere spiegati in modo così dettagliato come dovrebbero.

6.1. Un primo client Flex

Ora scriveremo un primo client Flex per visualizzare l'elenco dei clienti. L'architettura client/server che implementeremo è la seguente:

In questa architettura sono presenti due server web:

  • il server Glassfish che esegue il servizio web remoto
  • il server Apache che esegue il client Flex per il servizio web remoto

Stiamo sviluppando il client Flex utilizzando l'IDE Flex Builder 3:

  • In Flex Builder 3, creare un nuovo progetto in [1]
  • gli diamo un nome in [2] e specifichiamo in [3] in quale cartella generarlo
  • in [4], si assegna un nome all'applicazione principale (quella che verrà eseguita)
  • in [5], il progetto una volta generato
  • in [6], il file MXML principale dell’applicazione
  • Un file MXML contiene una vista e il codice di gestione degli eventi per quella vista. La scheda [Source] [7] consente di accedere al file MXML. Lì troverete i tag <mx> che descrivono la vista, oltre al codice ActionScript.
  • La vista può essere creata graficamente utilizzando la scheda [Design] [8]. I tag MXML che descrivono la vista vengono quindi generati automaticamente nella scheda [Source]. È vero anche il contrario: i tag MXML aggiunti direttamente nella scheda [Source] vengono visualizzati graficamente nella scheda [Design].

Come fatto con i precedenti client C# e ASP.NET, genereremo il proxy C locale [B] per il servizio web remoto S [A]:

Affinché il proxy C venga generato, il servizio web JEE deve essere attivo.

  • In [1], selezionare l'opzione Dati / Importa servizio Web
  • In [2], selezionare la cartella in cui generare le classi e le interfacce del proxy C.
  • In [3], inserire l'URI del file WSDL per il servizio web remoto S (vedere la sezione 4.10.2), quindi procedere al passaggio successivo
  • In [4] e [5], il servizio web descritto dal file WSDL specificato in [3]
  • In [6]: l'elenco dei metodi che saranno generati per il proxy C. Si noti che questi non sono i metodi effettivi del servizio S. Non hanno la firma corretta. Qui, ogni metodo elencato ha un unico parametro indipendentemente dal numero di parametri nel metodo effettivo del servizio web. Questo unico parametro è un'istanza di classe che incapsula nei propri campi i parametri previsti dal metodo remoto.
  • in [7]: il pacchetto in cui verranno generate le classi e le interfacce del proxy C
  • in [8]: il nome della classe locale che fungerà da proxy per il servizio web remoto
  • in [9]: completare la procedura guidata.
  • in [10]: l'elenco delle classi e delle interfacce del proxy C generato.
  • in [11]: la classe [WsDaoJpaService] che implementa i metodi del proxy C.

La classe [WsDaoJpaService] generata implementa la seguente interfaccia [IWsDaoJpaService]:


/**
 * Service.as
 * This file was auto-generated from WSDL by the Apache Axis2 generator modified by Adobe
 * Any change made to this file will be overwritten when the code is re-generated.
 */
package generated.webservices{
    import mx.rpc.AsyncToken;
    import flash.utils.ByteArray;
    import mx.rpc.soap.types.*;
 
    public interface IWsDaoJpaService
    {
        //Stub functions for the getAllClients operation
        /**
         * Call the operation on the server passing in the arguments defined in the WSDL file
         * @param getAllClients
         * @return An AsyncToken
         */
        function getAllClients(getAllClients:GetAllClients):AsyncToken;
....
        function getAllClients_send():AsyncToken;
...
        function get getAllClients_lastResult():GetAllClientsResponse;
...
        function set getAllClients_lastResult(lastResult:GetAllClientsResponse):void;
...
       function addgetAllClientsEventListener(listener:Function):void;
...
        function get getAllClients_request_var():GetAllClients_request;
...
        function set getAllClients_request_var(request:GetAllClients_request):void;
...
    }
}
  • riga 11: l'interfaccia [IWsDaoJpaService] implementata dalla classe [WsDaoJpaService]
  • righe 19–31: i vari metodi generati per il metodo getAllClients() del servizio web remoto. L'unico che corrisponde da vicino a quello effettivamente esposto dal servizio web è quello alla riga 19. Ha il nome corretto ma non la firma corretta: il metodo getAllClients() del servizio web remoto non ha parametri.

L'unico parametro del metodo getAllClients nel proxy C generato è del seguente tipo GetAllClients:


/**
 * GetAllClients.as
 * This file was auto-generated from WSDL by the Apache Axis2 generator modified by Adobe
 * Any change made to this file will be overwritten when the code is re-generated.
 */
 
package generated.webservices
{
    import mx.utils.ObjectProxy;
    import flash.utils.ByteArray;
    import mx.rpc.soap.types.*;
    /**
     * Wrapper class for a operation required type
     */
 
    public class GetAllClients
    {
        /**
         * Constructor, initializes the type class
         */
        public function GetAllClients() {}
 
    }
}

Questa è una classe vuota. Ciò potrebbe essere dovuto al fatto che il metodo di destinazione getAllClients non accetta alcun parametro.

Ora esaminiamo le classi generate per le entità Doctor, Client, Appointment e Time Slot. Diamo un'occhiata, ad esempio, alla classe Client:


package generated.webservices
{
    import mx.utils.ObjectProxy;
    import flash.utils.ByteArray;
    import mx.rpc.soap.types.*;
 
    public class Client extends generated.webservices.Personne
    {
        public function Client() {}
 
    }
}

Anche la classe Client è vuota. Deriva (riga 7) dalla seguente classe Person:


package generated.webservices
{
    import mx.utils.ObjectProxy;
    import flash.utils.ByteArray;
    import mx.rpc.soap.types.*;
 
    public class Personne
    {
        public function Personne() {}
 
        public var id:Number;
        public var nom:String;
        public var prenom:String;
        public var titre:String;
        public var version:Number;
    }
}
  • Righe 11–15: Questi sono gli attributi della classe Person definiti all'interno del servizio web JEE.

Ora disponiamo degli elementi principali del proxy C. Possiamo ora utilizzarlo.

Il file principale del client [rdvmedecins01.xml] è il seguente:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init();">
    <mx:Script>
        <![CDATA[
            import generated.webservices.Client;
...
 
            // données
            private var ws:WsDaoJpaService;
            [Bindable]
            private var clients:ArrayCollection;
 
            private function init():void{
...
            }
 
            private function loadClients():void{
...
            }
 
...            
            private function displayClient(client:Client):String{
...
            } 
        ]]>
    </mx:Script>
    <mx:Label text="Liste des clients" fontSize="14"/>
    <mx:List dataProvider="{clients}" labelFunction="displayClient"></mx:List>
    <mx:Button label="Afficher les clients" click="loadClients()"/>
    <mx:Text id="txtMsgErreur" width="454" height="75"/>
 
</mx:Application>

In questo codice, occorre distinguere diversi elementi:

  • la definizione dell'applicazione (riga 2)
  • la descrizione della sua vista (righe 27–30)
  • i gestori di eventi ActionScript all'interno del tag <mx:Script> (righe 3–26).

Cominciamo con il definire l'applicazione stessa e descriverne l'interfaccia:

  • riga 2: definisce
    • il layout dei componenti all'interno del contenitore della vista. L'attributo layout="vertical" indica che i componenti saranno disposti uno sotto l'altro.
    • il metodo da eseguire quando la vista è stata istanziata, ovvero quando tutti i suoi componenti sono stati istanziati. L'attributo creationComplete="init();" indica che deve essere eseguito il metodo init alla riga 13. creationComplete è uno degli eventi che la classe Application può emettere.
  • Le righe 27–30 definiscono i componenti della vista
  • Riga 27: definisce un testo
  • Riga 28: un elenco che conterrà l'elenco dei clienti. Il tag dataProvider="{clients}" specifica l'origine dati che popolerà l'elenco. In questo caso, l'elenco verrà popolato con l'oggetto clients definito alla riga 11. Per poter scrivere dataProvider="{clients}", il campo clients deve avere l'attributo [Bindable] (riga 10). Questo attributo consente di fare riferimento a una variabile ActionScript al di fuori del tag <mx:Script>. Il campo clients è di tipo ArrayCollection, un tipo ActionScript che consente di memorizzare elenchi di oggetti — in questo caso, un elenco di oggetti di tipo Client.
  • Riga 29: un pulsante. Il suo evento click viene gestito. L'attributo click="loadClients()" indica che il metodo loadClients alla riga 17 deve essere eseguito quando si fa clic sul pulsante. Questo pulsante attiverà la richiesta al servizio web per l'elenco dei clienti.
  • Riga 30: una casella di testo destinata a visualizzare eventuali messaggi di errore che potrebbero essere restituiti dal server in risposta alla richiesta precedente.

Le righe 27-30 generano la seguente vista nella scheda [Design]:

  • [1]: generato dal componente Label alla riga 27
  • [2]: generato dal componente List alla riga 28
  • [3]: generato dal componente Button alla riga 29
  • [4]: generato dal componente Text alla riga 30
  • [5]: un esempio di esecuzione

Esaminiamo ora il codice ActionScript della pagina. Questo codice gestisce gli eventi della vista.


<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init();">
 
    <mx:Script>
        <![CDATA[
            import generated.webservices.Client;
...
 
            // données
            private var ws:WsDaoJpaService;
            [Bindable]
            private var clients:ArrayCollection;
 
            private function init():void{
                // on instancie le proxy du service web
                ws=new WsDaoJpaService();
                // on configure les gestionnaires d'évts
                ws.addgetAllClientsEventListener(loadClientsCompleted);
                ws.addEventListener(FaultEvent.FAULT,loadClientsFault);
            }
 
            private function loadClients():void{
                // on demande la liste des clients
                ws.getAllClients(new GetAllClients());
            }
 
            private function loadClientsCompleted(event:GetAllClientsResultEvent):void{
                // on récupère les clients dans le résultat envoyé
                clients=event.result as ArrayCollection;
            }
 
            private function loadClientsFault(event:FaultEvent):void{
                // on affiche le msg d'erreur
                txtMsgErreur.text=event.fault.message;
            }
 
            private function displayClient(client:Client):String{
                // on affiche un client
                return client.nom + " " + client.prenom;
            } 
        ]]>
    </mx:Script>
    <mx:Label text="Liste des clients" fontSize="14"/>
    <mx:List dataProvider="{clients}" labelFunction="displayClient"></mx:List>
    <mx:Button label="Afficher les clients" click="loadClients()"/>
<mx:Text id="txtMsgErreur" width="454" height="75"/>
 
  • Riga 9: ws fa riferimento al proxy C di tipo WsDaoJpaService, la classe generata in precedenza che implementa i metodi per l'accesso al servizio web remoto.
  • riga 13: il metodo init viene eseguito quando la vista viene istanziata (riga 1)
  • riga 15: viene creata un'istanza del proxy C
  • riga 17: un gestore di eventi viene associato all'evento "il metodo asincrono GetAllClients è stato completato con successo". Per qualsiasi metodo m del servizio web remoto, il proxy C implementa un metodo addmEventListener che consente di associare un gestore di eventi all'evento "il metodo asincrono m è stato completato con successo". Qui, la riga 17 indica che il metodo loadClientsCompleted alla riga 26 deve essere eseguito quando il client Flex ha ricevuto l'elenco dei client.
  • Riga 18: un gestore di eventi è associato all'evento "un metodo asincrono del proxy C si è concluso con un errore". Qui, la riga 18 indica che il metodo loadClientsFault alla riga 31 deve essere eseguito ogni volta che una richiesta asincrona dal proxy C al servizio web S fallisce. In questo caso, l'unica richiesta che verrà effettuata è quella che richiede l'elenco dei client.
  • Infine, il metodo init alla riga 13 ha istanziato il proxy C e ha definito i gestori di eventi per la richiesta asincrona che verrà effettuata in seguito.
  • Riga 21: Il metodo eseguito quando si fa clic sul pulsante [Visualizza clienti] (riga 44)
  • Riga 23: viene eseguito il metodo asincrono getAllClients del proxy C. Gli viene passata un'istanza GetAllClients responsabile dell'incapsulamento dei parametri del metodo remoto chiamato. Qui non ci sono parametri. Viene creata un'istanza vuota. Il metodo getAllClients è asincrono. L'esecuzione prosegue senza attendere i dati restituiti dal server. In particolare, l'utente può continuare a interagire con la vista. Gli eventi attivati dall'utente continueranno a essere gestiti. Grazie al metodo init, sappiamo che:
    • il metodo loadClientsCompleted (riga 26) verrà eseguito quando il client Flex avrà ricevuto l'elenco dei clienti
    • il metodo loadClientsFault (riga 31) verrà eseguito se la richiesta termina con un errore.
  • Riga 28: L'elenco dei clienti viene recuperato dall'evento. Sappiamo che il metodo getAllClients del servizio web remoto restituisce un elenco. Inseriamo questo elenco nel campo clients alla riga 11. È necessario un type cast. Poiché l'elenco alla riga 43 è associato al campo clients, viene notificato che i suoi dati sono cambiati. Viene quindi visualizzato l'elenco dei clienti. Verrà visualizzata ogni voce dell'elenco dei clienti utilizzando il metodo displayClient (riga 43).
  • Riga 36: Il metodo displayClient accetta un tipo Client. Deve restituire la stringa che l'elenco deve visualizzare per questo cliente. In questo caso, il nome e il cognome (riga 38).
  • Riga 31: Il metodo eseguito quando una richiesta al servizio web fallisce. Riceve un parametro di tipo FaultEvent. Questa classe ha un campo `fault` che incapsula l'errore restituito dal server. `fault.message` è il messaggio che accompagna l'errore.
  • Riga 33: Il messaggio di errore viene visualizzato nella casella di testo prevista a tale scopo.

Una volta compilata l'applicazione, il codice eseguibile si trova nella cartella [bin-debug] del progetto Flex:

Sopra,

  • il file [rdvmedecins01.html] rappresenta il file HTML che il browser richiederà al server web per ottenere il client Flex
  • il file [rdvmedecins01.swf] è il binario del client Flex che verrà incorporato nella pagina HTML inviata al browser e successivamente eseguito dal plugin Flash Player del browser.

Siamo pronti per eseguire il client Flex. Per prima cosa, dobbiamo configurare l'ambiente di runtime necessario. Torniamo all'architettura client/server che abbiamo testato:

Lato server:

  • Avvia il DBMS MySQL
  • Avviare il server GlassFish
  • Distribuire il servizio web JEE per gli appuntamenti, se non è già stato distribuito
  • Facoltativamente, eseguire un test su uno dei client precedenti per verificare che tutto funzioni correttamente sul lato server.

Lato client:

Avviare il server Apache che ospiterà l'applicazione Flex. In questo caso utilizziamo lo strumento Wamp. Con questo strumento, possiamo assegnare un alias alla cartella [bin-debug] del progetto Flex.

  • L'icona di Wamp si trova nella parte inferiore dello schermo [1]
  • Fai clic con il tasto sinistro del mouse sull'icona di Wamp, seleziona l'opzione Apache [2] / Directory alias [3, 4]
  • Seleziona l'opzione [5]: Aggiungi un alias
  • In [6], assegnare un alias (un nome qualsiasi) all'applicazione web che verrà eseguita
  • In [7], specifica la radice dell'applicazione web che utilizzerà questo alias: si tratta della cartella [bin-debug] del progetto Flex che abbiamo appena creato.

Esaminiamo la struttura della cartella [bin-debug] nel progetto Flex:

Il file [rdvmedecins01.html] è il file HTML dell'applicazione Flex. Grazie all'alias appena creato per la cartella [bin-debug], è possibile accedere a questo file tramite l'URL [http://localhost/rdvmedecins/rdvmedecins01.html]. Accediamo a questo URL in un browser con il plugin Flash Player versione 9 o superiore:

  • in [1], l'URL dell'applicazione Flex
  • in [2], richiediamo l'elenco dei clienti
  • in [3], il risultato ottenuto quando tutto funziona correttamente
  • in [4], il risultato ottenuto quando richiediamo l'elenco dei clienti anche se il servizio web è stato arrestato.

Potresti essere curioso di vedere il codice sorgente della pagina HTML ricevuta

<!-- saved from url=(0014)about:internet -->
<html lang="en">

<!-- 
Smart developers always View Source. 

This application was built using Adobe Flex, an open source framework
for building rich Internet applications that get delivered via the
Flash Player or to desktops via Adobe AIR. 

Learn more about Flex at http://flex.org 
// -->

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<!--  BEGIN Browser History required section -->
<link rel="stylesheet" type="text/css" href="history/history.css" />
<!--  END Browser History required section -->

<title></title>
<script src="AC_OETags.js" language="javascript"></script>
...
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 124;
// -----------------------------------------------------------------------------
// -->
</script>
</head>

<body scroll="no">
<script language="JavaScript" type="text/javascript">
<!--
// Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
....
// -->
</script>
<noscript>
        <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
                        id="rdvmedecins01" width="100%" height="100%"
                        codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
                        <param name="movie" value="rdvmedecins01.swf" />
                        <param name="quality" value="high" />
                        <param name="bgcolor" value="#869ca7" />
                        <param name="allowScriptAccess" value="sameDomain" />
                        <embed src="rdvmedecins01.swf" quality="high" bgcolor="#869ca7"
                                width="100%" height="100%" name="rdvmedecins01" align="middle"
                                play="true"
                                loop="false"
                                quality="high"
                                allowScriptAccess="sameDomain"
                                type="application/x-shockwave-flash"
                                pluginspage="http://www.adobe.com/go/getflashplayer">
                        </embed>
        </object>
</noscript>
</body>
</html>

Il corpo della pagina inizia alla riga 39. Non contiene HTML standard, ma un oggetto (riga 47) di tipo "application/x-shockwave-flash" (riga 60). Si tratta del file [rdvmedecins01.swf] (riga 54) che si trova nella cartella [bin-debug] del progetto Flex. È un file di grandi dimensioni: circa 600 KB per questo semplice esempio.

6.2. Un secondo client Flex

Il secondo client Flex non utilizzerà il proxy C generato per il primo. Vogliamo dimostrare che questo passaggio non è essenziale, anche se offre dei vantaggi rispetto all'approccio che presenteremo qui.

Il progetto si evolve come segue:

  • in [1] la nuova applicazione Flex
  • in [2] gli eseguibili associati
  • in [3] la nuova vista: visualizzeremo l'elenco dei medici.

Il codice MXML dell'applicazione [rdvmedecins02.mxml] è il seguente:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
    <mx:Script>
        <![CDATA[
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
            import mx.collections.ArrayCollection;
 
            // données
            [Bindable]
            private var medecins:ArrayCollection;
 
            private function loadMedecins():void{
                // on demande la liste des médecins
                wsrdvmedecins.getAllMedecins.send();
            }
 
            private function loadMedecinsCompleted(event:ResultEvent):void{
                // on récupère les médecins
                medecins=event.result as ArrayCollection;
            }
 
            private function loadMedecinsFault(event:FaultEvent):void{
                // on affiche le msg d'erreur
                txtMsgErreur.text=event.fault.message;
            } 
 
            // affichage d'un médecin
            private function displayMedecin(medecin:Object):String{
                return medecin.nom + " " + medecin.prenom;
            } 
 
        ]]>
    </mx:Script>
    <mx:WebService id="wsrdvmedecins" 
        wsdl="http://localhost:8080/serveur-webservice-ejb-dao-jpa-hibernate/WsDaoJpaService?wsdl">
        <mx:operation name="getAllMedecins" 
            result="loadMedecinsCompleted(event)" fault="loadMedecinsFault(event);">
            <mx:request/>
        </mx:operation>
    </mx:WebService>
    <mx:Label text="Liste des médecins" fontSize="14"/>
    <mx:List dataProvider="{medecins}" labelFunction="displayMedecin"></mx:List>
    <mx:Button label="Afficher les médecins" click="loadMedecins()"/>
    <mx:Text id="txtMsgErreur" width="300" height="113"/>
 
</mx:Application>

Ci limiteremo a commentare le nuove funzionalità:

  • righe 42–45: la nuova vista. È identica alla precedente, tranne per il fatto che è stata adattata per visualizzare i medici anziché i clienti.
  • righe 35–41: il servizio web è descritto qui da un tag <mx:WebService> (riga 35). Il proxy C utilizzato nella versione precedente non viene più utilizzato qui.
  • riga 35: l'attributo id assegna un nome al servizio web.
  • riga 36: l'attributo wsdl specifica l'URI del file WSDL del servizio web. Si tratta dello stesso URI utilizzato dal client precedente e definito nella sezione 4.10.2.
  • Righe 37–40: definiscono un metodo del servizio web remoto utilizzando il tag <mx:operation>
  • Riga 37: il metodo a cui si fa riferimento è definito dall'attributo name. Qui facciamo riferimento al metodo remoto getAllMedecins.
  • Riga 38: Definiamo i metodi da eseguire se l'operazione ha esito positivo (attributo result) e se fallisce (attributo fault).
  • Riga 39: il tag <mx:request> viene utilizzato per definire i parametri dell'operazione. In questo caso, il metodo remoto getAllMedecins non ha parametri, quindi lo lasciamo vuoto. Per un metodo che accetta i parametri param1 e param2, scriveremmo:
<mx:Request>
    <param1>{param1}</param1>
    <param1>{param1}</param1>
</mx:Request>

dove param1 e param2 sarebbero variabili dichiarate e inizializzate all'interno del tag <mx:Script>

[Bindable]
private var param1:Type1;
[Bindable]
private var param2:Type2;

All'interno del tag <mx:Script> è presente del codice ActionScript simile a quello studiato nel client precedente. L'unica differenza è il metodo loadMedecins alle righe 13–16. È il modo in cui viene chiamato il metodo remoto [getAllMedecins] a differire:

  • riga 15: utilizziamo il servizio web [wsrdvmedecins] definito alla riga 35 e la sua operazione [getAllMedecins] definita alla riga 37. Per eseguire questa operazione, viene utilizzato il metodo send. Esso avvia la chiamata asincrona al metodo getAllMedecins del servizio web definito alla riga 35. Il metodo send effettuerà la chiamata con i parametri definiti dal tag <mx:request> alla riga 39. In questo caso, non ci sono parametri. Se il metodo avesse avuto i parametri param1 e param2, lo script loadMedecins avrebbe assegnato dei valori a questi parametri prima di chiamare il metodo send.

Non resta che testare questa nuova applicazione: