Skip to content

6. کلاینت‌های Flex برای سرویس قرار ملاقات JEE

اکنون دو کلاینت فلکس برای سرویس وب قرار ملاقات JEE ارائه می‌دهیم. نسخه فلکس بیلدر ۳ که استفاده شده IDE است. نسخه دمو این محصول را می‌توان از آدرس URL [https://www.adobe.com/cfusion/tdrc/index.cfm?loc=fr_fr&product=flex] دانلود کرد. Flex Builder 3 یک برنامه مبتنی بر Eclipse است. علاوه بر این، برای اجرای کلاینت Flex، از یک سرور وب Apache در ابزار Wamp استفاده می‌کنیم. هر سرور Apache کفایت می‌کند. مرورگری که کلاینت Flex را نمایش می‌دهد باید Flash Player نسخه ۹ یا بالاتر را نصب داشته باشد.

برنامه‌های فلکس از این جهت منحصر به فرد هستند که در داخل پلاگین Flash Player مرورگر اجرا می‌شوند. از این نظر، آنها شبیه به برنامه‌های Ajax هستند که اسکریپت‌ها را در صفحاتی که به مرورگر ارسال می‌شوند، جاسازی می‌کنند و سپس این اسکریپت‌ها در داخل مرورگر اجرا می‌شوند. یک برنامه فلیکس در معنای معمول یک برنامه وب نیست: این یک برنامه کلاینت برای خدماتی است که توسط سرورهای وب ارائه می‌شوند. از این نظر، مشابه یک برنامه دسکتاپ است که به عنوان کلاینت برای همان خدمات عمل می‌کند. با این حال، از یک جهت با آن تفاوت دارد: این برنامه در ابتدا از یک سرور وب دانلود شده و به داخل یک مرورگر مجهز به پلاگین Flash Player که قادر به اجرای آن است، منتقل می‌شود.

مانند یک برنامه دسکتاپ، یک برنامه فلکس عمدتاً از دو عنصر تشکیل شده است:

  • یک لایه ارائه: نماهای نمایش داده شده در مرورگر. این نماها همان غنای پنجره‌های برنامه‌های دسکتاپ را ارائه می‌دهند. یک نما با استفاده از یک زبان نشانه‌گذاری به نام MXML توصیف می‌شود.
  • یک مؤلفه کد که عمدتاً رویدادهای ناشی از اقدامات کاربر روی نما را مدیریت می‌کند. این کد همچنین می‌تواند به زبان MXML یا در یک زبان شیءگرا به نام ActionScript نوشته شود. باید بین دو نوع رویداد تمایز قائل شد:
  • یک رویداد که نیازمند ارتباط با سرور وب است: پر کردن یک لیست با داده‌های ارائه‌شده توسط یک برنامه وب، ارسال داده‌های فرم به سرور، و غیره. فلکس تعدادی روش برای ارتباط با سرور به گونه‌ای که برای توسعه‌دهنده شفاف باشد، فراهم می‌کند. این روش‌ها به طور پیش‌فرض غیرهمزمان هستند: کاربر می‌تواند در حالی که درخواست به سرور در حال پردازش است، به تعامل با نما ادامه دهد.
  • یک رویداد که نمای نمایش‌داده‌شده را بدون تبادل داده با سرور تغییر می‌دهد، برای مثال، کشیدن یک آیتم از یک درخت و رها کردن آن در یک لیست. این نوع رویداد به طور کامل به صورت محلی در مرورگر مدیریت می‌شود.

یک برنامه فلکس اغلب به شکل زیر اجرا می‌شود:

  • در [1]، یک صفحه HTML درخواست می‌شود
  • در [2]، ارسال می‌شود. این شامل یک فایل باینری، SWF (فلش ShockWave)، است که کل برنامه Flex را در خود جای داده است: تمام نماها و کد مربوط به پردازش رویدادهای آن‌ها. این فایل توسط افزونه FlashPlayer مرورگر اجرا خواهد شد.
  • کلاینت فلکس به صورت محلی در داخل مرورگر اجرا می‌شود، مگر زمانی که به داده‌های خارجی نیاز داشته باشد. در این صورت، این داده‌ها را از سرور [3] درخواست می‌کند. این داده‌ها را در قالب [4] در فرمت‌های مختلفی دریافت می‌کند: XML یا باینری. برنامه‌ای که روی سرور وب فراخوانی می‌شود می‌تواند به هر زبانی نوشته شود. تنها چیزی که اهمیت دارد، فرمت پاسخ است.

ما معماری زمان اجرای یک برنامه فلکس را به گونه‌ای توصیف کرده‌ایم که خواننده بتواند تفاوت آن را با معماری یک برنامه وب سنتی، بدون اجکس، مانند برنامه Asp.Net که قبلاً توضیح داده شد، به وضوح درک کند. در مورد دوم، مرورگر منفعل است: آن صرفاً صفحات HTML تولید شده در سرور وب را که به مرورگر ارسال می‌شوند، نمایش می‌دهد.

در بخش بعدی، ما دو مثال از کلاینت‌های Flex را صرفاً به منظور نشان دادن تنوع کلاینت‌ها برای یک سرویس وب ارائه می‌دهیم. از آنجایی که نویسنده خود یک تازه‌کار در زمینه Flex است، ممکن است برخی نکات به اندازه لازم با جزئیات توضیح داده نشده باشند.

6.1. یک مشتری Flex اولیه

اکنون اولین کلاینت فلکس خود را برای نمایش لیست کلاینت‌ها می‌نویسیم. معماری کلاینت/سروری که پیاده‌سازی خواهیم کرد به شرح زیر است:

در این معماری، دو وب‌سرور وجود دارد:

  • سرور GlassFish که سرویس وب راه دور را اجرا می‌کند
  • سرور آپاچی که کلاینت فلکس را برای سرویس وب راه دور اجرا می‌کند

ما کلاینت فلکس را با استفاده از IDE Flex Builder 3 می‌سازیم:

  • در Flex Builder 3، ما یک پروژه جدید در [1] ایجاد می‌کنیم
  • در [2] به آن یک نام می‌دهیم و در [3] پوشه‌ای را که باید در آن تولید شود، مشخص می‌کنیم
  • در [4]، به برنامهٔ اصلی (همان که اجرا خواهد شد) یک نام بدهید
  • در [5]، پروژه‌ای که یک‌بار تولید می‌شود
  • در [6]، فایل اصلی برنامه MXML
  • یک فایل به نام MXML حاوی یک نما و کد رسیدگی به رویدادهای آن نما است. زبانه‌ی [Source] [7] دسترسی به فایل MXML را فراهم می‌کند. این فایل حاوی تگ‌های <mx> است که نما را توصیف می‌کنند و همچنین کد ActionScript.
  • این نما را می‌توان به‌صورت گرافیکی با استفاده از برگه‌های [Design] و [8] ساخت. سپس تگ‌های MXML که نما را توصیف می‌کنند، به‌طور خودکار در برگه [Source] تولید می‌شوند. برعکس نیز صادق است: تگ‌های MXML که مستقیماً به تب [Source] اضافه می‌شوند، به‌صورت گرافیکی در تب [Design] منعکس می‌شوند.

همان‌طور که در مورد کلاینت‌های قبلی C# و Asp.Net انجام شد، ما پروکسی C محلی [B] را برای سرویس وب S راه دور [A] تولید خواهیم کرد:

برای تولید پروکسی C، سرویس وب JEE باید فعال باشد.

  • در [1]، گزینه Data / Import Web Service را انتخاب کنید
  • در [2]، پوشهٔ مربوط به تولید کلاس‌ها و رابط‌های پروکسی C را انتخاب کنید.
  • در [3]، URI فایل WSDL را برای سرویس وب راه دور S وارد کنید (به بخش 4.10.2 مراجعه کنید)، سپس به مرحله بعدی بروید
  • در [4] و [5]، سرویس وب توصیف‌شده توسط فایل WSDL که در [3] مشخص شده است
  • در [6]: فهرست متدهایی که برای پروکسی C تولید خواهند شد. توجه داشته باشید که این‌ها متدهای واقعی سرویس S نیستند. آن‌ها امضای صحیح را ندارند. در اینجا، هر متد نمایش داده شده صرف‌نظر از تعداد پارامترهای متد سرویس وب واقعی، یک پارامتر واحد دارد. این پارامتر واحد، نمونه‌ای از کلاسی است که پارامترهای مورد انتظار متد راه دور را در فیلدهای خود دربر می‌گیرد.
  • در [7]: پکیجی که کلاس‌ها و رابط‌های پروکسی C در آن تولید خواهند شد
  • در [8]: نام کلاس محلی که به‌عنوان پروکسی برای سرویس وب راه دور عمل خواهد کرد
  • در [9]: جادوگر را تکمیل کنید.
  • در [10]: فهرست کلاس‌ها و رابط‌های پروکسی C تولیدشده.
  • در [11]: کلاسی که متدهای پروکسی C را پیاده‌سازی می‌کند.

کلاس تولیدشده [WsDaoJpaService] رابط زیر [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 برای عملیات 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;
...
    }
}
  • خط ۱۱: رابط [IWsDaoJpaService] که توسط کلاس [WsDaoJpaService] پیاده‌سازی شده است
  • خطوط ۱۹–۳۱: متدهای مختلفی که برای متد getAllClients() سرویس وب راه دور تولید شده‌اند. تنها موردی که به متدی که واقعاً توسط سرویس وب ارائه شده نزدیک است، مورد خط ۱۹ است. این مورد نام صحیح را دارد اما امضای صحیح را ندارد: متد getAllClients() سرویس وب راه دور هیچ پارامتری ندارد.

تنها پارامتر متد getAllClients در پروکسی C تولیدشده از نوع زیر 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() {}
            
    }
}

این یک کلاس خالی است. این ممکن است به این دلیل باشد که متد هدف getAllClients هیچ پارامتری را قبول نمی‌کند.

حال بیایید کلاس‌های تولیدشده برای انتیت‌های Medecin، Client، Rv و Creneau را بررسی کنیم. بیایید کلاس 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() {}
            
    }
}

کلاس Client نیز خالی است. این کلاس (خط ۷) از کلاس زیر، Personne، ارث می‌برد:


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;
    }
}
  • خطوط ۱۱–۱۵: این‌ها شامل ویژگی‌های کلاس Personne هستند که در سرویس وب JEE تعریف شده‌اند.

اکنون عناصر اصلی پروکسی C را داریم. اکنون می‌توانیم از آن استفاده کنیم.

فایل اصلی کلاینت، [rdvmedecins01.xml]، به شرح زیر است:


<?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;
...
            
            // داده‌ها
            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>

در این کد، چندین عنصر باید از هم متمایز شوند:

  • تعریف برنامه (خط ۲)
  • توضیح نمای آن (خطوط 27–30)
  • پردازشگرهای رویداد در زبان ActionScript درون تگ <mx:Script> (خطوط ۳–۲۶).

بیایید با اظهار نظر در مورد تعریف خودِ برنامه و توضیح نمای آن شروع کنیم:

  • خط ۲: تعریف می‌کند
    • چیدمان اجزا در داخل کانتینر نما. ویژگی layout="vertical" مشخص می‌کند که اجزا به‌صورت پشت سر هم چیده شوند.
    • متدی که پس از نمونه‌سازی نما اجرا می‌شود، c.a.d. نقطه‌ای که در آن همهٔ اجزای آن نمونه‌سازی شده‌اند. ویژگی creationComplete="init();" نشان می‌دهد که متد init در خط 13 باید اجرا شود. creationComplete یکی از رویدادهایی است که کلاس Application می‌تواند صادر کند.
  • خطوط ۲۷–۳۰ کامپوننت‌های نما را تعریف می‌کنند
  • خط ۲۷: مقداری متن را تعریف می‌کند
  • خط ۲۸: یک لیست که لیست مشتریان در آن قرار خواهد گرفت. تگ dataProvider="{clients}" منبع داده‌هایی را که برای پر کردن لیست استفاده می‌شود، مشخص می‌کند. در اینجا، لیست با شیء clients که در خط ۱۱ تعریف شده است، پر خواهد شد. برای نوشتن dataProvider="{clients}"، فیلد clients باید دارای ویژگی [Bindable] (خط ۱۰) باشد. این ویژگی اجازه می‌دهد متغیر ActionScript خارج از تگ <mx:Script> ارجاع داده شود. میدان clients از نوع ArrayCollection است، یک نوع ActionScript که امکان ذخیره لیست اشیاء را فراهم می‌کند؛ در این مورد، یک لیست از اشیاء از نوع Client.
  • خط ۲۹: یک دکمه. رویداد click آن مدیریت می‌شود. ویژگی click="loadClients()" نشان می‌دهد که متد loadClients در خط 17 باید هنگام کلیک روی دکمه اجرا شود. این دکمه است که درخواست لیست مشتریان را به سرویس وب ارسال می‌کند.
  • خط ۳۰: یک کادر متن برای نمایش هرگونه پیام خطا که ممکن است توسط سرور در پاسخ به درخواست قبلی بازگردانده شود.

خطوط 27 تا 30 نمای زیر را در زبانه [Design] تولید می‌کنند:

  • [1]: تولید شده توسط کامپوننت Label در خط 27
  • [2]: توسط کامپوننت List در خط ۲۸ تولید شد
  • [3]: توسط کامپوننت Button در خط ۲۹ تولید شد
  • [4]: توسط مؤلفه Text در سطر ۳۰ تولید شد
  • [5]: مثالی از اجرا

بیایید اکنون کد ActionScript را در صفحه بررسی کنیم. این کد رویدادهای نما را مدیریت می‌کند.


<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init();">

    <mx:Script>
        <![CDATA[
            import generated.webservices.Client;
...
            
            // داده‌ها
            private var ws:WsDaoJpaService;
            [Bindable]
            private var clients:ArrayCollection;
            
            private function init():void{
                // نمونه سازی پروکسی سرویس وب
                ws=new WsDaoJpaService();
                // پردازشگرهای رویداد پیکربندی شده‌اند
                ws.addgetAllClientsEventListener(loadClientsCompleted);
                ws.addEventListener(FaultEvent.FAULT,loadClientsFault);
            }
            
            private function loadClients():void{
                //درخواست فهرست مشتریان
                ws.getAllClients(new GetAllClients());
            }
            
            private function loadClientsCompleted(event:GetAllClientsResultEvent):void{
                //بازیابی مشتریان از نتیجه بازگشتی
                clients=event.result as ArrayCollection;
            }
            
            private function loadClientsFault(event:FaultEvent):void{
                //نمایش پیام خطا
                txtMsgErreur.text=event.fault.message;
            }
            
            private function displayClient(client:Client):String{
                // نمایش یک مشتری
                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"/>

  • خط ۹: ws به پروکسی C از نوع WsDaoJpaService اشاره دارد، کلاسی که قبلاً ایجاد شده و متدهای دسترسی به سرویس وب راه دور را پیاده‌سازی می‌کند.
  • خط ۱۳: متد init زمانی اجرا می‌شود که ویو نمونه برداری می‌شود (خط ۱)
  • خط ۱۵: یک نمونه از پروکسی C ایجاد می‌شود
  • خط 17: یک رویدادپرداز با رویداد «متد غیرهمزمان GetAllClients با موفقیت تکمیل شد» مرتبط می‌شود. برای هر متد m سرویس وب راه دور، پروکسی C یک متد addmEventListener را پیاده‌سازی می‌کند که به یک هندلر اجازه می‌دهد با رویداد «متد غیرهمزمان m با موفقیت تکمیل شد» مرتبط شود. در اینجا، خط 17 مشخص می‌کند که متد loadClientsCompleted در خط 26 باید زمانی اجرا شود که کلاینت Flex لیست کلاینت‌ها را دریافت کرده است.
  • خط ۱۸: یک رویدادگیر با رویداد «یک متد غیرهمزمان پروکسی C با موفقیت ناقص شده است» مرتبط می‌شود. در اینجا، خط ۱۸ مشخص می‌کند که متد loadClientsFault در خط ۳۱ باید هر زمان که یک درخواست ناهمزمان از پروکسی C به سرویس وب S با شکست مواجه شود، اجرا گردد. در این حالت، تنها درخواستی که ارسال خواهد شد، درخواستی است که فهرست مشتریان را درخواست می‌کند.
  • در نهایت، متد init در خط ۱۳، پروکسی C را ایجاد کرده و رسیدگی‌کننده‌های رویداد را برای درخواست ناهمزمانی که بعداً انجام خواهد شد، تعریف می‌کند.
  • خط ۲۱: متدی که هنگام کلیک روی دکمه [Afficher les clients] (خط ۴۴) اجرا می‌شود
  • خط ۲۳: متد غیرهم‌زمان getAllClients از پروکسی C اجرا می‌شود. یک نمونه GetAllClients که مسئول دربرگیری پارامترهای متد راه دوری است که فراخوانی می‌شود، به آن پاس داده می‌شود. در این مورد، هیچ پارامتری وجود ندارد. یک نمونه خالی ایجاد می‌شود. متد getAllClients غیرهمزمان است. اجرای آن بدون انتظار برای داده‌های بازگشتی از سرور ادامه می‌یابد. به ویژه، کاربر می‌تواند به تعامل با نما ادامه دهد. هر رویدادی که توسط کاربر ایجاد شود، همچنان پردازش خواهد شد. به لطف متد init، می‌دانیم که:
    • روش loadClientsCompleted (خط ۲۶) زمانی اجرا می‌شود که کلاینت Flex فهرست مشتریان را دریافت کرده باشد
    • متد loadClientsFault (خط ۳۱) در صورتی که درخواست با خطا پایان یابد، اجرا خواهد شد.
  • خط ۲۸: لیست مشتریان از رویداد بازیابی می‌شود. می‌دانیم که متد getAllClients سرویس وب راه دور یک لیست را برمی‌گرداند. ما این را در فیلد clients در خط ۱۱ قرار می‌دهیم. تبدیل نوع لازم است. از آنجایی که لیست در خط ۴۳ به فیلد «clients» متصل است، به آن اطلاع داده می‌شود که داده‌هایش تغییر کرده است. سپس لیست مشتریان را نمایش می‌دهد. این کار با استفاده از متد displayClient (خط ۴۳) برای نمایش هر عنصر لیست clients انجام می‌شود.
  • خط ۳۶: متد displayClient یک پارامتر از نوع Client دریافت می‌کند. این متد باید رشته‌ای را که لیست برای این مشتری نمایش می‌دهد، بازگرداند. در این مورد، نام خانوادگی و نام (خط ۳۸).
  • خط ۳۱: متدی که هنگام شکست درخواست به سرویس وب اجرا می‌شود. این متد یک پارامتر از نوع FaultEvent دریافت می‌کند. این کلاس یک فیلد از نوع fault دارد که خطای بازگشتی از سرور را در خود جای می‌دهد. fault.message پیامی است که همراه با خطا می‌آید.
  • خط ۳۳: پیام خطا در کادر متنی ارائه‌شده برای این منظور نمایش داده می‌شود.

پس از ساخت اپلیکیشن، کد اجرایی آن در پوشه [bin-debug] پروژه Flex قرار دارد:

بالا،

  • فایل [rdvmedecins01.html] نمایانگر فایل HTML است که مرورگر برای دریافت کلاینت فلکس از سرور وب درخواست خواهد کرد.
  • فایل [rdvmedecins01.swf] باینری کلاینت فلکس است که در صفحه HTML ارسال‌شده به مرورگر جاسازی شده و سپس توسط افزونه Flash Player مرورگر اجرا می‌شود.

اکنون آماده اجرای کلاینت فلکس هستیم. اما ابتدا باید محیط زمان اجرای مورد نیاز آن را راه‌اندازی کنیم. بیایید به معماری کلاینت/سرور که در حال آزمایش آن بوده‌ایم بازگردیم:

سمت سرور:

  • SGBD MySQL را راه‌اندازی کنید
  • سرور GlassFish را راه‌اندازی کنید
  • سرویس وب JEE برای قرار ملاقات‌ها را مستقر کنید، اگر قبلاً مستقر نشده است
  • در صورت لزوم، یکی از کلاینت‌های قبلی را آزمایش کنید تا مطمئن شوید همه چیز در سمت سرور آماده است.

سمت کلاینت:

سرور آپاچی را که از آن درخواست برنامه فلکس انجام می‌شود، راه‌اندازی کنید. در اینجا از ابزار Wamp استفاده می‌کنیم. با این ابزار می‌توانیم یک نام مستعار (alias) به پوشه [bin-debug] پروژه فلکس اختصاص دهیم.

  • آیکون Wamp در پایین صفحه [1] قرار دارد
  • روی آیکون Wamp کلیک چپ کنید، سپس گزینه Apache [2] / مسیرهای مستعار [3, 4] را انتخاب کنید
  • گزینه [5]: افزودن یک نام مستعار را انتخاب کنید
  • در [6]، یک نام مستعار (هر نامی) برای برنامه وبی که قرار است اجرا شود، وارد کنید
  • در [7]، ریشهٔ برنامهٔ وبی را که از این نام مستعار استفاده خواهد کرد مشخص کنید: این پوشهٔ [bin-debug] پروژهٔ Flex است که همین حالا ساخته‌ایم.

بیایید ساختار پوشه [bin-debug] برای پروژه Flex را مرور کنیم:

فایل [rdvmedecins01.html]، فایل HTML مربوط به برنامه Flex است. به لطف نام مستعار (alias) که همین‌الان برای پوشه [bin-debug] ایجاد کردیم، می‌توان از طریق نشانی (URL) [http://localhost/rdvmedecins/rdvmedecins01.html] به این فایل دسترسی داشت. ما با استفاده از افزونه Flash Player نسخه ۹ یا جدیدتر، به این URL در یک مرورگر دسترسی پیدا می‌کنیم:

  • به [1]، URL برنامه Flex
  • به [2]، فهرست مشتریان را درخواست می‌کنیم
  • در [3]، نتیجهٔ به‌دست‌آمده زمانی که همه چیز به‌درستی کار می‌کند
  • در [4]، نتیجه‌ای که هنگام درخواست فهرست مشتریان در حالی که سرویس وب متوقف شده است، به دست می‌آید.

ممکن است بخواهید کد منبع صفحه HTML دریافت‌شده را مشاهده کنید

<!--ذخیره شده از 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 بخش مورد نیاز تاریخچه مرورگر -->
<link rel="stylesheet" type="text/css" href="history/history.css" />
<!--   END بخش مورد نیاز تاریخچه مرورگر -->

<title></title>
<script src="AC_OETags.js" language="javascript"></script>
...
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// متغیرهای سراسری
// نیاز به نسخهٔ اصلی فلش
var requiredMajorVersion = 9;
// نسخه جزئی فلش مورد نیاز
var requiredMinorVersion = 0;
// نسخه جزئی فلش مورد نیاز
var requiredRevision = 124;
// -----------------------------------------------------------------------------
// -->
</script>
</head>

<body scroll="no">
<script language="JavaScript" type="text/javascript">
<!--
//بررسی نسخه برای Flash Player قادر به اجرای نصب محصول Player (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>

بدنهٔ صفحه از خط ۳۹ آغاز می‌شود. این بخش شامل HTML استاندارد نیست، بلکه یک شیء (خط ۴۷) از نوع «application/x-shockwave-flash» (خط ۶۰) است. این فایل [rdvmedecins01.swf] (خط ۵۴) است که می‌توان آن را در پوشه [bin-debug] پروژه Flex یافت. این یک فایل بزرگ است: تقریباً ۶۰۰ کیلوبایت برای این مثال ساده.

6.2. یک کلاینت دوم فلکس

کلاینت دوم Flex از پروکسی C تولیدشده برای کلاینت اول استفاده نخواهد کرد. ما می‌خواهیم نشان دهیم که این مرحله ضروری نیست، هرچند مزایایی نسبت به رویکردی که در اینجا ارائه خواهد شد، دارد.

پروژه به شرح زیر تکامل می‌یابد:

  • به [1]، برنامه جدید Flex
  • به [2]، فایل‌های اجرایی مرتبط
  • به [3]، نمای جدید: فهرست پزشکان را نمایش خواهیم داد.

کد MXML برای برنامه [rdvmedecins02.mxml] به شرح زیر است:


<?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;
            
            // داده‌ها
            [Bindable]
            private var medecins:ArrayCollection;
            
            private function loadMedecins():void{
                // درخواست فهرست پزشکان
                wsrdvmedecins.getAllMedecins.send();
            }
            
            private function loadMedecinsCompleted(event:ResultEvent):void{
                // پزشکان بازیابی شدند
                medecins=event.result as ArrayCollection;
            }
            
            private function loadMedecinsFault(event:FaultEvent):void{
                // نمایش پیام خطا
                txtMsgErreur.text=event.fault.message;
            } 
            
            // نمایش پزشک
            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>

ما فقط دربارهٔ ویژگی‌های جدید توضیح می‌دهیم:

  • خطوط ۴۲–۴۵: نمای جدید. این نما دقیقاً مشابه نمای قبلی است، با این تفاوت که برای نمایش پزشکان به‌جای مشتریان تطبیق داده شده است.
  • خطوط ۳۵–۴۱: سرویس وب در اینجا با یک تگ <mx:WebService> (خط ۳۵) توصیف شده است. پروکسی C که در نسخه قبلی استفاده می‌شد، در اینجا دیگر استفاده نمی‌شود.
  • خط ۳۵: ویژگی id به سرویس وب نامی اختصاص می‌دهد.
  • خط ۳۶: ویژگی wsdl نشانی URI فایل سرویس وب WSDL را مشخص می‌کند. این همان URI است که توسط مشتری قبلی استفاده شده و در بخش ۴.۱۰.۲ تعریف شده است.
  • خطوط ۳۷–۴۰: یک متد از سرویس وب راه دور را با استفاده از تگ <mx:operation> تعریف می‌کنند
  • خط ۳۷: متد مرجع توسط ویژگی name تعریف می‌شود. در اینجا، ما به متد راه دور getAllMedecins اشاره می‌کنیم.
  • خط ۳۸: متدهایی که در صورت موفقیت عملیات (ویژگی result) و در صورت خطا (ویژگی fault) اجرا می‌شوند، تعریف شده‌اند.
  • خط ۳۹: تگ <mx:request> برای تعریف پارامترهای عملیات استفاده می‌شود. در اینجا، متد راه دور getAllMedecins هیچ پارامتری ندارد، بنابراین آن را خالی می‌گذاریم. برای متدی که پارامترها را می‌پذیرد param1 و param2، به این صورت می‌نویسیم:
<mx:Request>
    <param1>{param1}</param1>
    <param1>{param1}</param1>
</mx:Request>

که در آن param1 و param2 متغیرهایی هستند که درون تگ <mx:Script> تعریف و مقداردهی اولیه شده‌اند

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

در داخل تگ <mx:Script>، کد ActionScript مشابه کدی است که در کلاینت قبلی بررسی شد. تنها تفاوت، متد loadMedecins در خطوط ۱۳–۱۶ است. آنچه متفاوت است، نحوه فراخوانی متد راه دور [getAllMedecins] است:

  • خط ۱۵: سرویس وب [wsrdvmedecins] که در خط ۳۵ تعریف شده و عملیات آن [getAllMedecins] که در خط ۳۷ تعریف شده، استفاده می‌شوند. متد `send` برای اجرای این عملیات استفاده می‌شود. این امر، فراخوانی غیرهمزمان متد getAllMedecins سرویس وب تعریف‌شده در خط ۳۵ را آغاز می‌کند. متد send این فراخوانی را با استفاده از پارامترهای تعریف‌شده توسط تگ <mx:request> در خط ۳۹ انجام خواهد داد. در این مورد، هیچ پارامتر وجود ندارد. اگر متد دارای پارامترهای param1 و param2 بود، اسکریپت loadMedecins قبل از فراخوانی متد send، مقادیری را به این پارامترها اختصاص می‌داد.

تنها کاری که باقی مانده، آزمایش این برنامه جدید است: