Skip to content

6. Flex-Clients des Termindienstes JEE

Wir stellen nun zwei Flex-Clients des Webdienstes JEE für Termine vor. Als Flex Builder 3 wird IDE 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 ein IDE Eclipse. Um den Flex-Client auszuführen, verwenden wir außerdem einen Apache-Webserver des Wamp-Tools [http://www.wampserver.com/]. Jeder Apache-Server ist dafür geeignet. Der Browser, der den Flex-Client anzeigt, muss über das Flash Player-Plugin in mindestens Version 9 verfügen.

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 in die an den Browser gesendeten Seiten Skripte eingebettet sind, die anschließend im Browser ausgeführt werden. Eine Flex-Anwendung ist keine Webanwendung im herkömmlichen Sinne: Sie ist eine Client-Anwendung für Dienste, die von Webservern bereitgestellt werden. In dieser Hinsicht ähnelt sie einer Desktop-Anwendung, die ebenfalls Client dieser Dienste wäre. In einem Punkt unterscheidet sie sich jedoch: Sie wird zunächst von einem Webserver in einen Browser heruntergeladen, der über das Flash Player-Plugin verfügt, mit dem sie ausgeführt werden kann.

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

  • einem Präsentationsteil: den im Browser angezeigten Ansichten. Diese Ansichten sind so umfangreich wie die Fenster von Desktop-Anwendungen. Eine Ansicht wird mithilfe einer Auszeichnungssprache namens MXML beschrieben.
  • einem Codeteil, der hauptsächlich die 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. Dabei sind zwei Arten von Ereignissen zu unterscheiden:
  • das Ereignis, das einen Datenaustausch mit dem Webserver erfordert: das Ausfü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, um für den Entwickler transparent mit dem Server zu kommunizieren. Diese Methoden sind standardmäßig asynchron: Der Benutzer kann während der Anfrage an den Server weiterhin mit der Ansicht interagieren.
  • das Ereignis, das die angezeigte Ansicht ohne Datenaustausch mit dem Server verändert, zum Beispiel das Ziehen eines Elements aus einem Baum, um es in einer Liste abzulegen. 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 Binärdatei SWF (ShockWave Flash), die die gesamte Flex-Anwendung umfasst: alle Ansichten und den Code zur Ereignisverwaltung dieser Ansichten. Diese Datei wird vom Browser-Plugin FlashPlayer ausgeführt.
  • Die Ausführung des Flex-Clients erfolgt lokal im Browser, es sei denn, er benötigt externe Daten. In diesem Fall fordert er diese vom Server [3] an. Er erhält sie im Format [4] in verschiedenen Formaten: XML oder binär. Die auf dem Webserver abgefragte Anwendung kann in einer beliebigen Sprache geschrieben sein. Entscheidend ist lediglich das Format der Antwort.

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

Im Folgenden stellen wir zwei Beispiele für Flex-Clients vor, um die Vielfalt der Clients eines Webdienstes zu veranschaulichen. Da der Autor selbst noch Flex-Anfänger ist, werden einige Punkte möglicherweise nicht so ausführlich behandelt, wie es eigentlich erforderlich wäre.

6.1. Ein erster Flex-Client

Wir schreiben nun einen ersten Flex-Client, um die Kundenliste anzuzeigen. Die eingesetzte Client-Server-Architektur sieht wie folgt aus:

In dieser Architektur gibt es zwei Webserver:

  • der Glassfish-Server, auf dem der Remote-Webdienst ausgeführt wird
  • der Apache-Server, auf dem der Flex-Client des Remote-Webdienstes ausgeführt wird

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

  • In Flex Builder 3 erstellen wir ein neues Projekt unter [1]
  • Wir geben ihm einen Namen in [2] und legen in [3] fest, in welchem Ordner er generiert werden soll
  • In [4] gibt man der Hauptanwendung (die ausgeführt werden soll) einen Namen
  • In [5] wird das generierte Projekt
  • in [6]: die Hauptdatei der Anwendung MXML
  • Eine Datei mit dem Namen MXML enthält eine Ansicht und den Code zur Ereignisbehandlung dieser Ansicht. Die Registerkarte [Source] [7] ermöglicht den Zugriff auf die Datei MXML. Dort finden sich <mx>-Tags, die die Ansicht beschreiben, sowie Code ActionScript.
  • Die Ansicht kann grafisch mithilfe der Registerkarte [Design] [8] erstellt werden. Die die Ansicht beschreibenden Tags MXML werden dann automatisch in der Registerkarte [Source] generiert. Das Gegenteil trifft ebenfalls zu: Die Tags MXML, die direkt auf der Registerkarte [Source] hinzugefügt werden, werden grafisch auf der Registerkarte [Design] abgebildet.

Wie bereits bei den vorherigen C#-Clients und Asp.Net werden wir nun den lokalen C-Proxy [B] für den entfernten Webdienst S [A] generieren:

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

  • Wählen Sie in [1] die Option „Data / Import Web Service“
  • in [2] den Ordner für die Generierung der C-Proxy-Klassen und -Schnittstellen auswählen.
  • In [3] die URI der Datei WSDL des Remote-Webdienstes S eingeben (siehe Abschnitt 4.10.2) und dann zum nächsten Schritt übergehen
  • in [4] und [5]: den Webdienst, der durch die in [3] angegebene Datei WSDL beschrieben wird
  • in [6]: die Liste der Methoden, die für den Proxy C generiert werden. Es ist zu beachten, dass es sich hierbei nicht um die tatsächlichen Methoden des Dienstes S handelt. Sie weisen nicht die richtige Signatur auf. Hier hat jede dargestellte Methode einen einzigen Parameter, unabhängig von der Anzahl der Parameter der tatsächlichen Methode des Webdienstes. Dieser einzige Parameter ist eine Klasseninstanz, die in ihren Feldern die von der Remote-Methode erwarteten Parameter kapselt.
  • in [7]: das Paket, in dem die Klassen und Schnittstellen des C-Proxys generiert werden
  • in [8]: der Name der lokalen Klasse, die als Proxy zum entfernten Webdienst fungiert
  • 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 Methoden des C-Proxys 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-Funktionen für die Operation getAllClients
        /**
         * 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 generierten Methoden für die Methode getAllClients() des Remote-Webdienstes. Die einzige, die der tatsächlich vom Webdienst bereitgestellten Methode nahekommt, ist die in Zeile 19. Sie trägt zwar den richtigen Namen, hat aber nicht die richtige Signatur: Die Methode getAllClients() des Remote-Webdienstes hat keine Parameter.

Der einzige Parameter der Methode getAllClients des generierten C-Proxys ist vom Typ GetAllClients wie folgt:


/**
 * 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. Dies könnte darauf hindeuten, dass die Zielmethode getAllClients keine Parameter zulässt.

Sehen wir uns nun die generierten Klassen für die Entitäten Medecin, Client, Rv und Creneau 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 Personne 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: Hier finden sich die Attribute der Klasse Personne, die innerhalb des Webdienstes JEE definiert ist.

Wir haben nun die wichtigsten Elemente des Proxys C. Wir können ihn nun verwenden.

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


<?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;
...
            
            // Daten
            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 verschiedene Dinge zu unterscheiden:

  • die Definition der Anwendung (Zeile 2)
  • die Beschreibung der Ansicht (Zeilen 27–30)
  • die Ereignisbehandler in der Sprache ActionScript innerhalb des Tags <mx:Script> (Zeilen 3–26).

Betrachten wir zunächst die Definition der Anwendung selbst und die Beschreibung ihrer Ansicht:

  • Zeile 2: definiert
    • die Anordnung der Komponenten im Container der Ansicht. Das Attribut layout="vertical" gibt an, dass die Komponenten untereinander angeordnet werden.
    • die Methode, die ausgeführt werden soll, sobald die Ansicht instanziiert wurde: c.a.d. den Zeitpunkt, zu dem alle ihre Komponenten instanziiert wurden. Das Attribut creationComplete="init();" gibt an, dass die Methode init aus 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 einen Text
  • Zeile 28: eine Liste, in die die Kundenliste eingefügt wird. Das Tag dataProvider="{clients}" gibt die Datenquelle an, aus der die Liste gefüllt werden soll. Hier wird die Liste mit dem in Zeile 11 definierten Objekt clients gefüllt. Um dataProvider="{clients}" schreiben zu können, muss das Feld clients das Attribut [Bindable] (Zeile 10) besitzen. Dieses Attribut ermöglicht es, außerhalb des Tags <mx:Script> auf eine Variable ActionScript zu verweisen. Das Feld clients ist vom Typ ArrayCollection, einem Typ ActionScript, der das Speichern von Objektlisten ermöglicht, in diesem Fall einer Liste von Objekten vom Typ Client.
  • Zeile 29: eine Schaltfläche. Ihr Ereignis click wird abgehandelt. Das Attribut click="loadClients()" gibt an, dass die Methode loadClients aus Zeile 17 bei einem Klick auf die Schaltfläche ausgeführt werden soll. Diese Schaltfläche löst die Anfrage an den Webdienst zur Abfrage der Kundenliste aus.
  • Zeile 30: Ein Textfeld zur Anzeige einer eventuellen Fehlermeldung, die vom Server als Antwort auf die vorherige Anfrage zurückgesendet würde.

Die Zeilen 27–30 erzeugen die folgende Ansicht auf der Registerkarte „[Design]“:

  • [1]: wurde von der Komponente Label aus Zeile 27 generiert
  • [2]: wurde von der Komponente List in Zeile 28 generiert
  • [3]: wurde von der Komponente Button in Zeile 29 generiert
  • [4]: wurde von der Komponente Text in Zeile 30 generiert
  • [5]: Ein Ausführungsbeispiel

Betrachten wir nun den Code ActionScript auf der Seite. Dieser Code verwaltet 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;
...
            
            // Daten
            private var ws:WsDaoJpaService;
            [Bindable]
            private var clients:ArrayCollection;
            
            private function init():void{
                // Der Webservice-Proxy wird instanziiert
                ws=new WsDaoJpaService();
                // Konfiguration der Ereignisbehandler
                ws.addgetAllClientsEventListener(loadClientsCompleted);
                ws.addEventListener(FaultEvent.FAULT,loadClientsFault);
            }
            
            private function loadClients():void{
                // Die Liste der Clients wird angefordert
                ws.getAllClients(new GetAllClients());
            }
            
            private function loadClientsCompleted(event:GetAllClientsResultEvent):void{
                // Die Clients werden aus dem übermittelten Ergebnis abgerufen
                clients=event.result as ArrayCollection;
            }
            
            private function loadClientsFault(event:FaultEvent):void{
                // Die Fehlermeldung wird angezeigt
                txtMsgErreur.text=event.fault.message;
            }
            
            private function displayClient(client:Client):String{
                // Ein Kunde wird angezeigt
                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 bezeichnet den Proxy C 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 wurde (Zeile 1)
  • Zeile 15: Eine Instanz des Proxys C wird erstellt
  • Zeile 17: Dem Ereignis „Die asynchrone Methode GetAllClients wurde erfolgreich abgeschlossen“ wird ein Ereignishandler zugewiesen. Für jede Methode m des Remote-Webdienstes implementiert der C-Proxy eine Methode addmEventListener, die es ermöglicht, dem Ereignis „Die asynchrone Methode m wurde erfolgreich abgeschlossen“ einen Handler zuzuordnen. Hier gibt Zeile 17 an, dass die Methode loadClientsCompleted aus Zeile 26 ausgeführt werden soll, sobald der Flex-Client die Kundenliste erhalten hat.
  • Zeile 18: Ein Ereignis-Handler wird dem Ereignis „Eine asynchrone Methode des C-Proxys ist fehlgeschlagen“ zugeordnet. Hier gibt Zeile 18 an, dass die Methode loadClientsFault aus Zeile 31 jedes Mal ausgeführt werden soll, wenn eine asynchrone Anfrage des C-Proxys an den Webdienst S fehlschlägt. Hier wird lediglich die Anfrage gestellt, die die Kundenliste anfordert.
  • Letztendlich hat die Methode init in Zeile 13 den C-Proxy instanziiert und Ereignisbehandler für die später stattfindende asynchrone Anfrage definiert.
  • Zeile 21: Die Methode, die beim Klicken auf die Schaltfläche [Afficher les clients] (Zeile 44) ausgeführt wird
  • Zeile 23: Die asynchrone Methode getAllClients des Proxys C wird ausgeführt. Ihr wird eine Instanz GetAllClients übergeben, die die Parameter der aufgerufenen Remote-Methode kapseln soll. 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. Der Benutzer kann insbesondere weiterhin mit der Ansicht interagieren. Die von ihm 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 Kundenliste erhalten hat
    • die Methode loadClientsFault (Zeile 31) ausgeführt wird, wenn die Anfrage mit einem Fehler endet.
  • Zeile 28: Die Kundenliste wird im Ereignis abgerufen. Wir wissen, dass die Methode getAllClients des Remote-Webdienstes eine Liste zurückgibt. Diese wird in das Feld clients in Zeile 11 geschrieben. Dabei ist eine Typkonvertierung erforderlich. Da die Liste in Zeile 43 mit dem Feld „Kunden“ verknüpft (Bindable) ist, wird sie darüber informiert, dass sich ihre Daten geändert haben. Daraufhin zeigt sie die Kundenliste an. Sie zeigt jedes Element der Liste clients mit der Methode displayClient (Zeile 43) an.
  • Zeile 36: Die Methode displayClient erhält einen Typ Client. Sie muss die Zeichenkette zurückgeben, die die Liste für diesen Kunden anzeigen soll. Hier sind das sind der Name und der Vorname (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 vom Typ fault, das den vom Server zurückgegebenen Fehler kapselt. fault.message ist die zum Fehler gehörende Meldung.
  • Zeile 33: Die Fehlermeldung wird im dafür vorgesehenen Textfeld angezeigt.

Nach der Erstellung der Anwendung 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 Binärdatei des Flex-Clients, 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. Zuvor müssen wir jedoch die dafür erforderliche Ausführungsumgebung einrichten. Kehren wir zur getesteten Client-Server-Architektur zurück:

Auf der Serverseite:

  • Starten Sie SGBD und MySQL
  • den Glassfish-Server starten
  • Den Webdienst JEE für Termine bereitstellen, falls er noch nicht bereitgestellt ist
  • Gegebenenfalls einen der oben genannten Clients testen, um zu überprüfen, ob auf der Serverseite alles funktioniert.

Auf der Client-Seite:

Starten Sie den Apache-Server, an den die Flex-Anwendung angefordert wird. Hier verwenden wir das Tool Wamp. 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]
  • Wählen Sie durch einen Linksklick auf das Symbol Wamp die Option Apache [2] / Alias Directories [3, 4]
  • die Option „[5]: Alias hinzufügen“ auswählen
  • In [6] geben Sie der Webanwendung, die ausgeführt werden soll, einen Alias (einen beliebigen Namen)
  • Geben Sie unter [7] das Stammverzeichnis der Webanwendung an, die diesen Alias tragen soll: Dies ist der Ordner [bin-debug] des Flex-Projekts, das wir gerade erstellt haben.

Zur Erinnerung: Die Struktur des Ordners [bin-debug] des Flex-Projekts sieht wie folgt aus:

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

  • in [1], die URL der Flex-Anwendung
  • in [2] rufen wir die Kundenliste ab
  • in [3] das Ergebnis, das man erhält, wenn alles gut läuft
  • in [4] das Ergebnis, das wir erhalten, wenn wir die Anzeige der Kunden anfordern, obwohl der Webdienst gestoppt wurde.

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

<!-- gespeichert von 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 Erforderlicher Abschnitt Browser-Verlauf -->
<link rel="stylesheet" type="text/css" href="history/history.css" />
<!--   END Abschnitt Browser-Verlauf erforderlich -->

<title></title>
<script src="AC_OETags.js" language="javascript"></script>
...
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globale Variablen
// Hauptversion von Flash erforderlich
var requiredMajorVersion = 9;
// Nebenversion von Flash erforderlich
var requiredMinorVersion = 0;
// Erforderliche Nebenversion von Flash
var requiredRevision = 124;
// -----------------------------------------------------------------------------
// -->
</script>
</head>

<body scroll="no">
<script language="JavaScript" type="text/javascript">
<!--
// Versionsprüfung für den Flash Player, der die Installation des Player-Produkts (6.0r65) starten kann
....
// -->
</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 klassisches HTML, sondern ein Objekt (Zeile 47) vom Typ „application/x-shockwave-flash“ (Zeile 60). Es handelt sich um die Datei [rdvmedecins01.swf] (Zeile 54), die im Ordner [bin-debug] des Flex-Projekts zu finden ist. Diese Datei ist recht groß: etwa 600 K 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 zwingend erforderlich ist, auch wenn er gegenüber dem hier vorgestellten Ansatz Vorteile bietet.

Das Projekt entwickelt sich wie folgt weiter:

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

Der Code MXML der 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;
            
            // Daten
            [Bindable]
            private var medecins:ArrayCollection;
            
            private function loadMedecins():void{
                // Die Liste der Ärzte wird angefordert
                wsrdvmedecins.getAllMedecins.send();
            }
            
            private function loadMedecinsCompleted(event:ResultEvent):void{
                // Die Ärzte werden abgerufen
                medecins=event.result as ArrayCollection;
            }
            
            private function loadMedecinsFault(event:FaultEvent):void{
                // Anzeige der Fehlermeldung
                txtMsgErreur.text=event.fault.message;
            } 
            
            // Anzeige eines Arztes
            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 Neuerungen eingehen:

  • Zeilen 42–45: die neue Ansicht. Sie ist identisch mit der vorherigen, wurde jedoch angepasst, um Ärzte statt Kunden anzuzeigen.
  • Zeilen 35–41: Der Webdienst wird hier durch das Tag <mx:WebService> (Zeile 35) beschrieben. Der in der vorherigen Version verwendete C-Proxy wird hier nicht mehr verwendet.
  • Zeile 35: Das Attribut id gibt dem Webdienst einen Namen.
  • Zeile 36: Das Attribut wsdl gibt die URI der Datei WSDL des Webdienstes an. Es handelt sich um dieselbe URI, die vom vorherigen Client verwendet wurde und in Abschnitt 4.10.2 definiert ist.
  • Zeilen 37–40: Definieren eine Methode des Remote-Webdienstes mithilfe des Tags <mx:operation>
  • Zeile 37: Die referenzierte Methode wird durch das Attribut name definiert. Hier verweisen wir auf die Remote-Methode getAllMedecins.
  • Zeile 38: Hier werden die Methoden definiert, die bei erfolgreichem Abschluss des Vorgangs (Attribut result) und bei Fehlschlag (Attribut fault) ausgeführt werden sollen.
  • Zeile 39: Das Tag <mx:request> dient zur Definition der Parameter des Vorgangs. Da die Remote-Methode getAllMedecins keine Parameter hat, geben wir hier nichts ein. Bei einer Methode, die die Parameter param1 und param2 akzeptiert, würde man schreiben:
<mx:Request>
    <param1>{param1}</param1>
    <param1>{param1}</param1>
</mx:Request>

wobei param1 und param2 im Tag <mx:Script> deklarierte und initialisierte Variablen wären

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

Im Tag <mx:Script> findet sich Code ActionScript, der dem im vorherigen Client untersuchten Code ähnelt. Lediglich die Methode loadMedecins in den Zeilen 13–16 unterscheidet sich. Der Aufruf der Remote-Methode [getAllMedecins] erfolgt hier anders:

  • Zeile 15: Es wird der in Zeile 35 definierte Webdienst [wsrdvmedecins] und dessen in Zeile 37 definierte Operation [getAllMedecins] verwendet. Zur Ausführung dieser Operation wird die Methode „send“ verwendet. Diese startet den asynchronen Aufruf der Methode getAllMedecins des in Zeile 35 definierten Webdienstes. Die Methode „send“ führt den Aufruf mit den Parametern durch, die durch das Tag <mx:request> 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 es die Methode send aufgerufen hätte.

Nun müssen wir diese neue Anwendung nur noch testen: