Skip to content

6. Flex-Clients für den JEE-Terminplanungsdienst

Wir stellen nun zwei Flex-Clients für den JEE-Webdienst für Termine vor. Als IDE wird Flex Builder 3 verwendet. Eine Demoversion dieses Produkts kann unter der URL [https://www.adobe.com/cfusion/tdrc/index.cfm?loc=fr_fr&product=flex] heruntergeladen werden. Flex Builder 3 ist eine Eclipse-IDE. Um den Flex-Client auszuführen, verwenden wir zusätzlich einen Apache-Webserver aus dem Wamp-Tool [http://www.wampserver.com/]. Jeder Apache-Server ist geeignet. Auf dem Browser, der den Flex-Client anzeigt, muss Flash Player Version 9 oder höher installiert sein.

Flex-Anwendungen zeichnen sich dadurch aus, dass sie innerhalb des Flash Player-Plugins des Browsers ausgeführt werden. In dieser Hinsicht ähneln sie Ajax-Anwendungen, bei denen JavaScript-Skripte in die an den Browser gesendeten Seiten eingebettet und dann im Browser ausgeführt werden. Eine Flex-Anwendung ist keine Webanwendung im üblichen Sinne: Es handelt sich um eine Client-Anwendung für Dienste, die von Webservern bereitgestellt werden. In dieser Hinsicht ist sie vergleichbar mit einer Desktop-Anwendung, die als Client für dieselben Dienste fungiert. In einem Punkt unterscheidet sie sich jedoch: Sie wird zunächst von einem Webserver in einen Browser heruntergeladen, der mit dem Flash Player-Plugin ausgestattet ist, das sie ausführen kann.

Wie eine Desktop-Anwendung besteht eine Flex-Anwendung im Wesentlichen aus zwei Elementen:

  • einer Präsentationsschicht: den im Browser angezeigten Ansichten. Diese Ansichten bieten denselben Funktionsumfang wie Fenster von Desktop-Anwendungen. Eine Ansicht wird mithilfe einer Markup-Sprache namens MXML beschrieben.
  • einer Codekomponente, die in erster Linie Ereignisse verarbeitet, die durch Benutzeraktionen auf der Ansicht ausgelöst werden. Dieser Code kann ebenfalls in MXML oder in einer objektorientierten Sprache namens ActionScript geschrieben werden. Es sind zwei Arten von Ereignissen zu unterscheiden:
  • Ereignisse, die eine Kommunikation mit dem Webserver erfordern: das Auffüllen einer Liste mit Daten, die von einer Webanwendung bereitgestellt werden, das Senden von Formulardaten an den Server usw. Flex bietet eine Reihe von Methoden für die Kommunikation mit dem Server, die für den Entwickler transparent ablaufen. Diese Methoden sind standardmäßig asynchron: Der Benutzer kann weiterhin mit der Ansicht interagieren, während die Serveranfrage läuft.
  • Ereignisse, die die angezeigte Ansicht ändern, ohne Daten mit dem Server auszutauschen, wie z. B. das Ziehen eines Elements aus einer Baumstruktur und das Ablegen in einer Liste. Diese Art von Ereignis wird vollständig lokal im Browser verarbeitet.

Eine Flex-Anwendung wird häufig wie folgt ausgeführt:

  • In [1] wird eine HTML-Seite angefordert
  • In [2] wird sie gesendet. Sie enthält eine SWF-Binärdatei (ShockWave Flash), die die gesamte Flex-Anwendung umfasst: alle Ansichten und deren Code zur Ereignisbehandlung. Diese Datei wird vom Flash Player-Plugin des Browsers ausgeführt.
  • Der Flex-Client läuft lokal im Browser, außer wenn er externe Daten benötigt. In diesem Fall fordert er diese vom Server an [3]. Er empfängt sie in [4] in verschiedenen Formaten: XML oder binär. Die auf dem Webserver abgefragte Anwendung kann in jeder beliebigen Sprache geschrieben sein. Es kommt nur auf das Antwortformat an.

Wir haben die Ausführungsarchitektur einer Flex-Anwendung beschrieben, damit der Leser den Unterschied zu einer herkömmlichen Webanwendung ohne Ajax, wie der zuvor beschriebenen Asp.Net-Anwendung, klar nachvollziehen kann. Bei letzterer ist der Browser passiv: Er zeigt lediglich HTML-Seiten an, die auf dem Webserver erstellt und an den Browser gesendet werden.

In den folgenden Abschnitten stellen wir zwei Beispiele für Flex-Clients vor, um die Vielfalt der Clients für einen Webdienst zu veranschaulichen. Da der Autor selbst ein Flex-Anfänger ist, werden einige Punkte möglicherweise nicht so ausführlich erklärt, wie es eigentlich erforderlich wäre.

6.1. Ein erster Flex-Client

Wir werden nun einen ersten Flex-Client erstellen, um die Liste der Clients anzuzeigen. Die Client-Server-Architektur, die wir implementieren werden, sieht wie folgt aus:

In dieser Architektur gibt es zwei Webserver:

  • der Glassfish-Server, auf dem der Remote-Webdienst läuft
  • der Apache-Server, auf dem der Flex-Client für den Remote-Webdienst läuft

Wir erstellen den Flex-Client mit der Flex Builder 3-IDE:

  • Erstellen Sie in Flex Builder 3 unter [1] ein neues Projekt
  • Wir geben ihm in [2] einen Namen und legen in [3] fest, in welchem Ordner es erstellt werden soll
  • In [4] benennen wir die Hauptanwendung (diejenige, die ausgeführt wird)
  • in [5] das Projekt, sobald es generiert ist
  • in [6] die Haupt-MXML-Datei der Anwendung
  • Eine MXML-Datei enthält eine Ansicht und den Code zur Ereignisbehandlung für diese Ansicht. Über die Registerkarte [Source] [7] können Sie auf die MXML-Datei zugreifen. Dort finden Sie <mx>-Tags, die die Ansicht beschreiben, sowie ActionScript-Code.
  • Die Ansicht kann grafisch über die Registerkarte [Design] [8] erstellt werden. Die MXML-Tags, die die Ansicht beschreiben, werden dann automatisch auf der Registerkarte [Source] generiert. Das Gegenteil trifft ebenfalls zu: MXML-Tags, die direkt auf der Registerkarte [Source] hinzugefügt werden, werden grafisch auf der Registerkarte [Design] angezeigt.

Wie bereits bei den vorherigen C#- und ASP.NET-Clients werden wir den lokalen C-Proxy [B] für den Remote-Webdienst S [A] generieren:

Damit der C-Proxy generiert werden kann, muss der JEE-Webdienst aktiv sein.

  • Wählen Sie unter [1] die Option „Daten / Webservice importieren
  • Wählen Sie unter [2] den Ordner für die Generierung der C-Proxy-Klassen und -Schnittstellen aus.
  • Geben Sie in [3] die URI der WSDL-Datei für den Remote-Webdienst S ein (siehe Abschnitt 4.10.2) und fahren Sie dann mit dem nächsten Schritt fort
  • In [4] und [5] den Webdienst, der durch die in [3] angegebene WSDL-Datei beschrieben wird
  • In [6]: die Liste der Methoden, die für den C-Proxy generiert werden. Beachten Sie, dass es sich hierbei nicht um die tatsächlichen Methoden des Dienstes S handelt. Sie weisen nicht die korrekte Signatur auf. Hier hat jede aufgeführte Methode einen einzigen Parameter, unabhängig von der Anzahl der Parameter in der tatsächlichen Webdienstmethode. Dieser einzelne Parameter ist eine Klasseninstanz, die die von der Remote-Methode erwarteten Parameter in ihren Feldern kapseln.
  • in [7]: das Paket, in dem die Klassen und Schnittstellen des Proxys C generiert werden
  • in [8]: Der Name der lokalen Klasse, die als Proxy für den Remote-Webdienst fungieren wird
  • in [9]: Beenden Sie den Assistenten.
  • in [10]: die Liste der Klassen und Schnittstellen des generierten C-Proxys.
  • in [11]: die Klasse [WsDaoJpaService], die die C-Proxy-Methoden implementiert.

Die generierte Klasse [WsDaoJpaService] implementiert die folgende Schnittstelle [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;
...
    }
}
  • Zeile 11: die Schnittstelle [IWsDaoJpaService], die von der Klasse [WsDaoJpaService] implementiert wird
  • Zeilen 19–31: die verschiedenen Methoden, die für die Methode getAllClients() des Remote-Webdienstes generiert wurden. Die einzige, die der tatsächlich vom Webdienst bereitgestellten Methode sehr nahe kommt, ist die in Zeile 19. Sie hat den richtigen Namen, aber nicht die richtige Signatur: Die Methode getAllClients() des Remote-Webdienstes hat keine Parameter.

Der einzige Parameter der getAllClients-Methode im generierten C-Proxy ist vom Typ 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() {}
 
    }
}

Dies ist eine leere Klasse. Das könnte daran liegen, dass die Zielmethode „getAllClients“ keine Parameter akzeptiert.

Sehen wir uns nun die generierten Klassen für die Entitäten „Doctor“, „Client“, „Appointment“ und „Time Slot“ an. Betrachten wir zum Beispiel die Klasse „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() {}
 
    }
}

Die Klasse „Client“ ist ebenfalls leer. Sie leitet sich (Zeile 7) von der folgenden Klasse „Person“ ab:


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;
    }
}
  • Zeilen 11–15: Dies sind die Attribute der Klasse „Person“, die innerhalb des JEE-Webdienstes definiert sind.

Wir haben nun die Hauptelemente des C-Proxys. Wir können ihn nun verwenden.

Die Hauptdatei des Clients [rdvmedecins01.xml] sieht wie folgt aus:


<?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 diesem Code sind mehrere Elemente zu unterscheiden:

  • die Anwendungsdefinition (Zeile 2)
  • die Beschreibung ihrer Ansicht (Zeilen 27–30)
  • die ActionScript-Ereignisbehandler innerhalb des <mx:Script>-Tags (Zeilen 3–26).

Beginnen wir damit, die Definition der Anwendung selbst und die Beschreibung ihrer Ansicht zu erörtern:

  • Zeile 2: definiert
    • das Layout der Komponenten innerhalb des View-Containers. Das Attribut layout="vertical" gibt an, dass die Komponenten untereinander angeordnet werden.
    • die Methode, die ausgeführt werden soll, wenn die Ansicht instanziiert wurde, d. h. wenn alle ihre Komponenten instanziiert wurden. Das Attribut creationComplete="init();" gibt an, dass die Methode init in Zeile 13 ausgeführt werden soll. creationComplete ist eines der Ereignisse, die die Klasse Application auslösen kann.
  • Die Zeilen 27–30 definieren die Komponenten der Ansicht
  • Zeile 27: definiert ein Textfeld
  • Zeile 28: eine Liste, die die Liste der Clients enthält. Das Tag dataProvider="{clients}" gibt die Datenquelle an, die die Liste füllt. Hier wird die Liste mit dem in Zeile 11 definierten clients-Objekt gefüllt. Um dataProvider="{clients}" schreiben zu können, muss das Feld clients das Attribut [Bindable] haben (Zeile 10). Dieses Attribut ermöglicht es, außerhalb des <mx:Script>-Tags auf eine ActionScript-Variable zu verweisen. Das Feld „clients“ ist vom Typ „ArrayCollection“, einem ActionScript-Typ, mit dem Sie Listen von Objekten speichern können – in diesem Fall eine Liste von Objekten vom Typ „Client“.
  • Zeile 29: eine Schaltfläche. Ihr Klick-Ereignis wird abgehandelt. Das Attribut click="loadClients()" gibt an, dass die Methode loadClients in Zeile 17 ausgeführt werden muss, wenn auf die Schaltfläche geklickt wird. Diese Schaltfläche löst die Anfrage an den Webdienst für die Liste der Clients aus.
  • Zeile 30: ein Textfeld, das dazu dient, etwaige Fehlermeldungen anzuzeigen, die vom Server als Antwort auf die vorherige Anfrage zurückgegeben werden könnten.

Die Zeilen 27–30 erzeugen die folgende Ansicht auf der Registerkarte [Entwurf]:

  • [1]: generiert durch die Label-Komponente in Zeile 27
  • [2]: generiert durch die List-Komponente in Zeile 28
  • [3]: generiert durch die Button-Komponente in Zeile 29
  • [4]: generiert durch die Text-Komponente in Zeile 30
  • [5]: ein Ausführungsbeispiel

Sehen wir uns nun den ActionScript-Code der Seite an. Dieser Code verarbeitet die Ereignisse der Ansicht.


<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"/>
 
  • Zeile 9: ws bezieht sich auf den C-Proxy vom Typ WsDaoJpaService, die zuvor generierte Klasse, die die Methoden für den Zugriff auf den Remote-Webdienst implementiert.
  • Zeile 13: Die Methode „init“ wird ausgeführt, wenn die Ansicht instanziiert wird (Zeile 1)
  • Zeile 15: Es wird eine Instanz des C-Proxys erstellt
  • Zeile 17: Ein Ereignis-Handler wird dem Ereignis „Die asynchrone Methode GetAllClients wurde erfolgreich abgeschlossen“ zugeordnet. Für jede Methode m des Remote-Webdienstes implementiert der C-Proxy eine addmEventListener-Methode, die es ermöglicht, einen Ereignis-Handler mit dem Ereignis „Die asynchrone Methode m wurde erfolgreich abgeschlossen“ zu verknüpfen. Hier gibt Zeile 17 an, dass die Methode loadClientsCompleted in Zeile 26 ausgeführt werden muss, wenn der Flex-Client die Liste der Clients empfangen hat.
  • Zeile 18: Ein Ereignisbehandler ist mit dem Ereignis „Eine asynchrone Methode des C-Proxys ist fehlgeschlagen“ verknüpft. Hier gibt Zeile 18 an, dass die Methode `loadClientsFault` in Zeile 31 ausgeführt werden muss, sobald eine asynchrone Anfrage vom C-Proxy an den Webdienst S fehlschlägt. Hier ist die einzige Anfrage, die gestellt wird, diejenige, die die Liste der Clients anfordert.
  • Letztendlich hat die Methode „init“ in Zeile 13 den C-Proxy instanziiert und Ereignisbehandler für die später zu sendende asynchrone Anfrage definiert.
  • Zeile 21: Die Methode, die ausgeführt wird, wenn die Schaltfläche [Display Clients] (Zeile 44) angeklickt wird
  • Zeile 23: Die asynchrone Methode „getAllClients“ des Proxys C wird ausgeführt. Ihr wird eine „GetAllClients“-Instanz übergeben, die für die Kapselung der Parameter der aufgerufenen Remote-Methode zuständig ist. Hier gibt es keine Parameter. Es wird eine leere Instanz erstellt. Die Methode „getAllClients“ ist asynchron. Die Ausführung wird fortgesetzt, ohne auf die vom Server zurückgegebenen Daten zu warten. Insbesondere kann der Benutzer weiterhin mit der Ansicht interagieren. Die vom Benutzer ausgelösten Ereignisse werden weiterhin verarbeitet. Dank der Methode „init“ wissen wir, dass:
    • die Methode `loadClientsCompleted` (Zeile 26) ausgeführt wird, sobald der Flex-Client die Liste der Clients erhalten hat
    • die Methode „loadClientsFault“ (Zeile 31) ausgeführt wird, wenn die Anfrage mit einem Fehler endet.
  • Zeile 28: Die Liste der Clients wird aus dem Ereignis abgerufen. Wir wissen, dass die Methode getAllClients des Remote-Webdienstes eine Liste zurückgibt. Wir speichern diese Liste in dem Feld clients in Zeile 11. Ein Typumwandlung ist erforderlich. Da die Liste in Zeile 43 an das Feld clients gebunden ist, wird ihr mitgeteilt, dass sich ihre Daten geändert haben. Sie zeigt daraufhin die Liste der Clients an. Sie zeigt jedes Element in der Clients-Liste mithilfe der Methode displayClient (Zeile 43) an.
  • Zeile 36: Die Methode „displayClient“ erwartet einen Typ „Client“. Sie muss die Zeichenfolge zurückgeben, die die Liste für diesen Client anzeigen soll. Hier sind das der Vor- und Nachname (Zeile 38).
  • Zeile 31: Die Methode, die ausgeführt wird, wenn eine Anfrage an den Webdienst fehlschlägt. Sie erhält einen Parameter vom Typ „FaultEvent“. Diese Klasse verfügt über ein Feld „fault“, das den vom Server zurückgegebenen Fehler kapselt. „fault.message“ ist die zum Fehler gehörige Meldung.
  • Zeile 33: Die Fehlermeldung wird in dem dafür vorgesehenen Textfeld angezeigt.

Sobald die Anwendung erstellt wurde, befindet sich ihr ausführbarer Code im Ordner [bin-debug] des Flex-Projekts:

Oben

  • stellt die Datei [rdvmedecins01.html] die HTML-Datei dar, die der Browser vom Webserver anfordert, um den Flex-Client zu erhalten
  • Die Datei [rdvmedecins01.swf] ist die Flex-Client-Binärdatei, die in die an den Browser gesendete HTML-Seite eingebettet und anschließend vom Flash Player-Plugin des Browsers ausgeführt wird.

Wir sind bereit, den Flex-Client auszuführen. Zunächst müssen wir die dafür erforderliche Laufzeitumgebung einrichten. Kehren wir zu der von uns getesteten Client-Server-Architektur zurück:

Auf der Serverseite:

  • Starten Sie das MySQL-DBMS
  • Starten Sie den GlassFish-Server
  • Stellen Sie den JEE-Webdienst für Termine bereit, falls dieser noch nicht bereitgestellt wurde
  • Testen Sie optional einen der vorherigen Clients, um zu überprüfen, ob auf der Serverseite alles ordnungsgemäß funktioniert.

Client-seitig:

Starten Sie den Apache-Server, auf dem die Flex-Anwendung gehostet wird. Hier verwenden wir das Wamp-Tool. Mit diesem Tool können wir dem Ordner [bin-debug] des Flex-Projekts einen Alias zuweisen.

  • Das Wamp-Symbol befindet sich am unteren Bildschirmrand [1]
  • Klicken Sie mit der linken Maustaste auf das Wamp-Symbol, wählen Sie die Option „Apache“ [2] / „Alias-Verzeichnisse“ [3, 4]
  • Wählen Sie die Option [5]: „Alias hinzufügen“
  • Geben Sie unter [6] einen Alias (beliebiger Name) für die Webanwendung ein, die ausgeführt werden soll
  • Geben Sie unter [7] das Stammverzeichnis der Webanwendung an, die diesen Alias verwenden soll: Dies ist der Ordner [bin-debug] des soeben erstellten Flex-Projekts.

Sehen wir uns die Struktur des Ordners [bin-debug] im Flex-Projekt an:

Die Datei [rdvmedecins01.html] ist die HTML-Datei für die Flex-Anwendung. Dank des Alias, den wir gerade für den Ordner [bin-debug] erstellt haben, kann auf diese Datei über die URL [http://localhost/rdvmedecins/rdvmedecins01.html] zugegriffen werden. Wir rufen diese URL in einem Browser mit dem Flash Player-Plugin der Version 9 oder höher auf:

  • in [1] die URL der Flex-Anwendung
  • in [2] fordern wir die Liste der Clients an
  • in [3] das Ergebnis, das man erhält, wenn alles korrekt funktioniert
  • in [4] das Ergebnis, das erhalten wird, wenn wir die Liste der Clients anfordern, obwohl der Webdienst gestoppt wurde.

Vielleicht möchten Sie sich den Quellcode der empfangenen HTML-Seite ansehen

<!-- 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>

Der Hauptteil der Seite beginnt in Zeile 39. Er enthält kein Standard-HTML, sondern ein Objekt (Zeile 47) vom Typ „application/x-shockwave-flash“ (Zeile 60). Dies ist die Datei [rdvmedecins01.swf] (Zeile 54), die sich im Ordner [bin-debug] des Flex-Projekts befindet. Es handelt sich um eine große Datei: etwa 600 KB für dieses einfache Beispiel.

6.2. Ein zweiter Flex-Client

Der zweite Flex-Client wird den für den ersten generierten C-Proxy nicht verwenden. Wir möchten zeigen, dass dieser Schritt nicht unbedingt erforderlich ist, auch wenn er gegenüber dem hier vorgestellten Ansatz Vorteile bietet.

Das Projekt entwickelt sich wie folgt:

  • in [1] die neue Flex-Anwendung
  • in [2] die zugehörigen ausführbaren Dateien
  • in [3] der neuen Ansicht: Wir zeigen die Liste der Ärzte an.

Der MXML-Code für die Anwendung [rdvmedecins02.mxml] lautet wie folgt:


<?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>

Wir werden nur auf die neuen Funktionen eingehen:

  • Zeilen 42–45: die neue Ansicht. Sie ist identisch mit der vorherigen, wurde jedoch so angepasst, dass sie Ärzte statt Kunden anzeigt.
  • Zeilen 35–41: Der Webdienst wird hier durch ein <mx:WebService>-Tag (Zeile 35) beschrieben. Der in der vorherigen Version verwendete C-Proxy wird hier nicht mehr verwendet.
  • Zeile 35: Das id-Attribut gibt dem Webdienst einen Namen.
  • Zeile 36: Das wsdl-Attribut gibt die URI der WSDL-Datei des Webdienstes an. Dies ist dieselbe URI, die vom vorherigen Client verwendet und in Abschnitt 4.10.2 definiert wurde.
  • Zeilen 37–40: Definieren Sie eine Methode des Remote-Webdienstes mithilfe des <mx:operation>-Tags
  • Zeile 37: Die referenzierte Methode wird durch das name-Attribut definiert. Hier referenzieren wir die Remote-Methode getAllMedecins.
  • Zeile 38: Wir definieren die Methoden, die ausgeführt werden sollen, wenn die Operation erfolgreich ist (Attribut „result“) und wenn sie fehlschlägt (Attribut „fault“).
  • Zeile 39: Das <mx:request>-Tag wird verwendet, um die Parameter der Operation zu definieren. Hier hat die Remote-Methode getAllMedecins keine Parameter, daher lassen wir das Feld leer. Für eine Methode, die die Parameter param1 und param2 akzeptiert, würden wir schreiben:
<mx:Request>
    <param1>{param1}</param1>
    <param1>{param1}</param1>
</mx:Request>

wobei param1 und param2 Variablen sind, die innerhalb des <mx:Script>-Tags deklariert und initialisiert werden

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

Innerhalb des <mx:Script>-Tags befindet sich ActionScript-Code, der dem im vorherigen Client behandelten ähnelt. Der einzige Unterschied besteht in der Methode loadMedecins in den Zeilen 13–16. Es ist die Art und Weise, wie die Remote-Methode [getAllMedecins] aufgerufen wird, die sich unterscheidet:

  • Zeile 15: Wir verwenden den in Zeile 35 definierten Webdienst [wsrdvmedecins] und dessen in Zeile 37 definierte Operation [getAllMedecins]. Zur Ausführung dieser Operation wird die Methode send verwendet. Sie initiiert den asynchronen Aufruf der Methode getAllMedecins des in Zeile 35 definierten Webdienstes. Die send-Methode führt den Aufruf mit den Parametern durch, die durch das <mx:request>-Tag in Zeile 39 definiert sind. Hier gibt es keine Parameter. Hätte die Methode die Parameter param1 und param2 gehabt, hätte das Skript loadMedecins diesen Parametern Werte zugewiesen, bevor die send-Methode aufgerufen wurde.

Nun muss diese neue Anwendung nur noch getestet werden: