Adobe Flex 3 ヘルプ

サービス結果の処理

RPC コンポーネントでサービスを呼び出すと、サービスから返されたデータが lastResult オブジェクトに格納されます。デフォルトでは、HTTPService コンポーネントおよび WebService コンポーネント処理の resultFormat プロパティ値は object であり、返されたデータは ActionScript オブジェクトの単純なツリーとして表現されます。Flex では、Web サービスや HTTP サービスから返された XML データが、String、Number、Boolean、Date などの基本型を表すように適切に解釈されます。厳密に型指定されたオブジェクトを扱う場合は、Flex により作成されたオブジェクトツリーを使用してそれらのオブジェクトを設定する必要があります。

WebService コンポーネントと HTTPService コンポーネントはいずれも、複合型である匿名のオブジェクトおよび配列を返します。makeObjectsBindable がデフォルトの true の場合、オブジェクトは mx.utils.ObjectProxy インスタンスにラップされ、配列は mx.collections.ArrayCollection インスタンスにラップされます。

注意: ColdFusion では大文字と小文字が区別されないため、データはすべて内部で大文字に変換されます。ColdFusion の Web サービスを利用する場合は、この点に注意してください。

result イベントと fault イベントの処理

サービス呼び出しが完了すると、RemoteObject のメソッド、WebService の処理、または HTTPService のコンポーネントから、result イベントまたは fault イベントが送出されます。「result イベント」は、使用できる結果が返されたことを示します。「fault イベント」は、エラーが発生したことを示します。result イベントは、lastResult にバインドされているプロパティを更新するトリガとして機能します。result イベントおよび fault イベントを明示的に処理するには、イベントリスナーを RemoteObject のメソッドまたは WebService の処理に追加します。HTTPService コンポーネントの場合は、result および fault イベントリスナーをコンポーネント自身で指定します。これは、HTTPService コンポーネントには複数の処理やメソッドがないためです。

RemoteObject のメソッドや WebService の処理で result または fault イベントのイベントリスナーを指定しない場合、イベントはコンポーネントレベルで渡されます。この場合、コンポーネントレベルの result および fault イベントリスナーを指定できます。

次の MXML の例では、WebService 処理の result および fault イベントでイベントリスナーを指定しています。また、WebService コンポーネントの fault イベントでもイベントリスナーを指定しています。

<?xml version="1.0"?>
<!-- fds\rpc\RPCResultFaultMXML.mxml --> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            import mx.rpc.soap.SOAPFault;         
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
            import mx.controls.Alert;
            public function showErrorDialog(event:FaultEvent):void {
                // Handle operation fault.
                Alert.show(event.fault.faultString, "Error");
            }
            public function defaultFault(event:FaultEvent):void {
                // Handle service fault.
                if (event.fault is SOAPFault) {
                     var fault:SOAPFault=event.fault as SOAPFault;
                     var faultElement:XML=fault.element;
                     // You could use E4X to traverse the raw fault element returned in the SOAP envelope.
                     // ...
                }
                Alert.show(event.fault.faultString, "Error");               
            }
            public function log(event:ResultEvent):void {
                // Handle result.
            }
        ]]>
    </mx:Script>
    <mx:WebService id="WeatherService" destination="wsDest"
        fault="defaultFault(event)">
        <mx:operation name="GetWeather"
            fault="showErrorDialog(event)"
            result="log(event)">
            <mx:request>
                <ZipCode>{myZip.text}</ZipCode>
            </mx:request>
        </mx:operation>
    </mx:WebService>
    <mx:TextInput id="myZip"/>  
</mx:Application>

次の ActionScript の例では、result イベントリスナーを WebService 処理に追加し、fault イベントリスナーを WebService コンポーネントに追加しています。

<?xml version="1.0"?>
<!-- fds\rpc\RPCResultFaultAS.mxml --> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            import mx.rpc.soap.WebService;
            import mx.rpc.soap.SOAPFault;             
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
          
            private var ws:WebService;
            
            public function useWebService(intArg:int, strArg:String):void {
                ws = new WebService();
                ws.destination = "wsDest";
                ws.echoArgs.addEventListener("result", echoResultHandler);
                ws.addEventListener("fault", faultHandler);
                ws.loadWSDL();
                ws.echoArgs(intArg, strArg);
            }

            public function echoResultHandler(event:ResultEvent):void {
                var retStr:String = event.result.echoStr;
                var retInt:int = event.result.echoInt;
                //do something
        }

            public function faultHandler(event:FaultEvent):void {
            //deal with event.fault.faultString, etc.
                if (event.fault is SOAPFault) {
                     var fault:SOAPFault=event.fault as SOAPFault;
                     var faultElement:XML=fault.element;
                     // You could use E4X to traverse the raw fault element returned in the SOAP envelope.
                     // ...
                }     
            }
        ]]>
    </mx:Script>    
</mx:Application>

また、mx.rpc.events.InvokeEvent イベントを使用して、データアクセスコンポーネント要求がいつ呼び出されたかを示すこともできます。このイベントは、処理をキューに格納して後で呼び出す場合に便利です。

結果を E4X 結果フォーマットの XML として処理する方法

HTTPService コンポーネントおよび WebService 処理の resultFormat プロパティ値を e4x に設定すると、XML 型の lastResult プロパティを作成できます。lastResult プロパティには E4X(ECMAScript for XML)式を使用してアクセスできます。E4X XML オブジェクトをバインディング式に使用する場合は、XML 構造体のルートノードをドット表記に含めないでください。これは、lastResult プロパティをオブジェクトに設定するときに、XML 構造体のルートノードをドット表記に含めるシンタックスとは異なります。例えば、lastResult プロパティを e4x に設定する場合は、{srv.lastResult.product} を使用し、lastResult プロパティをオブジェクトに設定する場合は、{srv.lastResult.products.product} を使用します。

e4x の結果フォーマットを使用する方法は XML を直接操作する場合に適していますが、resultFormat プロパティを xml に設定することによって、XML 操作用の古いオブジェクトである flash.xml.XMLNode 型の lastResult オブジェクトを作成することもできます。また、HTTPService コンポーネントの resultFormat プロパティを flashvars または text に設定することで、前者は名前と値のペアを含む ActionScript オブジェクトとして、後者は純粋なテキストだけを含む ActionScript オブジェクトとして、それぞれ結果を作成できます。

注意: サービス結果で E4X のシンタックスを使用するには、HTTPService または WebService コンポーネントの resultFormat プロパティを e4x に設定する必要があります。デフォルト値は object です。

HTTPService コンポーネントまたは WebService 処理の resultFormat プロパティを e4x に設定する場合は、返される XML に含まれる名前空間情報を処理する必要がある場合があります。WebService コンポーネントでは、名前空間情報は Web サービスを返す SOAP エンベロープのボディに含まれています。次の例は、名前空間情報を含む SOAP ボディの一部です。このデータは株式相場を取得する Web サービスから返されたものです。名前空間情報はボールドのテキストで示しています。

...
<soap:Body>
<GetQuoteResponse
xmlns="http://ws.invesbot.com/">
<GetQuoteResult><StockQuote xmlns="">
<Symbol>ADBE</Symbol>
<Company>ADOBE SYSTEMS INC</Company>
<Price>&lt;big&gt;&lt;b&gt;35.90&lt;/b&gt;&lt;/big&gt;</Price>
...
</soap:Body>
...

この soap:Body には名前空間情報が含まれているため、WebService 処理の resultFormat プロパティを e4x に設定した場合は、http://ws.invesbot.com/ 名前空間に対応する名前空間オブジェクトを作成する必要があります。次の例は、この処理を実行するアプリケーションです。

<?xml version="1.0"?>
<!-- fds\rpc\WebServiceE4XResult1.mxml --> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
    pageTitle="Test" >
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            private namespace invesbot = "http://ws.invesbot.com/";
            use namespace invesbot;
        ]]>
    </mx:Script>
    <mx:WebService
        id="WS"
        destination="stockservice" useProxy="true" 
        fault="Alert.show(event.fault.faultString), 'Error'">
        <mx:operation name="GetQuote" resultFormat="e4x">
            <mx:request>
                <symbol>ADBE</symbol>
            </mx:request>
        </mx:operation>
    </mx:WebService>
    <mx:HBox>
        <mx:Button label="Get Quote" click="WS.GetQuote.send()"/>
        <mx:Text
            text="{WS.GetQuote.lastResult.GetQuoteResult.StockQuote.Price}"
        />
    </mx:HBox>
</mx:Application>

次の例のように、名前空間用の変数を作成し、サービス結果へのバインディングの中で変数にアクセスすることもできます。

<?xml version="1.0"?>
<!-- fds\rpc\WebServiceE4XResult2.mxml --> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
    pageTitle="Test" >
    <mx:Script>
        <![CDATA[
        import mx.controls.Alert;
        public var invesbot:Namespace =
            new Namespace("http://ws.invesbot.com/");
        ]]>
    </mx:Script>
    <mx:WebService
        id="WS"
        destination="stockservice" useProxy="true" 
        fault="Alert.show(event.fault.faultString), 'Error'">
        <mx:operation name="GetQuote" resultFormat="e4x">
            <mx:request>
                <symbol>ADBE</symbol>
            </mx:request>
        </mx:operation>
    </mx:WebService>
    <mx:HBox>
        <mx:Button label="Get Quote" click="WS.GetQuote.send()"/>
        <mx:Text
          text="{WS.GetQuote.lastResult.invesbot::GetQuoteResult.StockQuote.Price}"
        />
    </mx:HBox>
</mx:Application>

E4X のシンタックスは、lastResult オブジェクトの中で返される XML のエレメントや属性にアクセスする場合に使用します。使用するシンタックスは、名前空間が XML で宣言されているかどうかによって異なります。

名前空間なし

次の例は、エレメントや属性で名前空間が指定されていない場合にエレメント値や属性値を取得する方法を示しています。

var attributes:XMLList = XML(event.result).Description.value;

前のコードは、次の XML ドキュメントの xxx を返します。

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <Description>
        <value>xxx</value>
    </Description>
</RDF>

任意の名前空間

次の例は、エレメントや属性で任意の名前空間が指定されている場合にエレメント値や属性値を取得する方法を示しています。

var attributes:XMLList = XML(event.result).*::Description.*::value;

前のコードは、次のいずれかの XML ドキュメントの xxx を返します。

XML ドキュメント 1:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description>
        <rdf:value>xxx</rdf:value>
    </rdf:Description>
</rdf:RDF>

XML ドキュメント 2:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cm="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <cm:Description>
        <rdf:value>xxx</rdf:value>
    </cm:Description>
</rdf:RDF>

特定の名前空間

次の例は、宣言された rdf 名前空間がエレメントや属性で指定されている場合にエレメント値や属性値を取得する方法を示しています。

var rdf:Namespace = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
var attributes:XMLList = XML(event.result).rdf::Description.rdf::value;

前のコードは、次の XML ドキュメントの xxx を返します。

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description>
        <rdf:value>xxx</rdf:value>
    </rdf:Description>
</rdf:RDF>

次の例は、宣言された rdf 名前空間がエレメントや属性で指定されている場合にエレメント値や属性値を取得する別の方法を示しています。

namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
use namespace rdf;
var attributes:XMLList = XML(event.result).rdf::Description.rdf::value;

前のコードは、次の XML ドキュメントの xxx を返します。

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description>
        <rdf:value>xxx</rdf:value>
    </rdf:Description>
</rdf:RDF>

.NET DataSet または DataTable を含む Web サービス結果の処理

Microsoft .NET Framework で記述された Web サービスは、特殊な .NET DataSet または DataTable オブジェクトをクライアントに返します。.NET Web サービスは、操作するデータ型に関する情報なしに、非常に基本的な WSDL ドキュメントを提供します。Web サービスが DataSet または DataTable を返すときに、データ型情報が SOAP メッセージの XML Schema エレメントに埋め込まれます。このメッセージは、残りのメッセージをどのように処理するかを指定します。このタイプの Web サービスの結果の最良の処理方法は、Flex WebService 処理の resultFormat プロパティを object に設定することです。WebService 処理の resultFormat プロパティを e4x に設定することもできますが、DataGrid コントロールなどにデータをバインドする場合に、通常とは異なる構造の応答を通じて移動し、回避する方法を実装しなければならないため、XML 形式と e4x 形式は使い勝手がよくありません。

Flex WebService 処理の resultFormat プロパティを object に設定する場合は、.NET Web サービスから返される DataTable または DataSet は、1 つまたは複数の dataTable オブジェクトのマップを含む Tables プロパティが組み込まれたオブジェクトに自動的に変換されます。Tables マップから提供される各 dataTable オブジェクトには、Columns および Rows の 2 つのプロパティが組み込まれています。Rows プロパティにはデータが含まれています。event.result オブジェクトは、.NET の DataSet および DataTable プロパティに対応する次のプロパティを取得します。DataSet または DataTable の配列には、ここで記述されたものと同じ構造体がありますが、結果オブジェクトの最上位レベルの配列にネストされています。

プロパティ

内容

result.Tables

テーブルデータを含むオブジェクトへのテーブル名のマップ。

result.Tables["someTable"].Columns

テーブルの DataSet または DataTable スキーマで指定された順序による列名の配列。

result.Tables["someTable"].Rows

各テーブル行のデータをï\すオブジェクトの配列。例えば、{columnName1:value, columnName2:value, columnName3:value}。

次の MXML アプリケーションは、DataGrid コントロールを .NET Web サービスから返された DataTable データに格納します。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
    <mx:WebService
        id="nwCL"
        wsdl="http://localhost/data/CustomerList.asmx?wsdl"
        result="onResult(event)"
        fault="onFault(event)" />
    <mx:Button label="Get Single DataTable" click="nwCL.getSingleDataTable()"/>
    <mx:Button label="Get MultiTable DataSet" click="nwCL.getMultiTableDataSet()"/>
    <mx:Panel id="dataPanel" width="100%" height="100%" title="Data Tables"/>

    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.controls.DataGrid;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;

            private function onResult(event:ResultEvent):void {
                // A DataTable or DataSet returned from a .NET webservice is
                // automatically converted to an object with a "Tables" property,
                // which contains a map of one or more dataTables.
                if (event.result.Tables != null)
                {
                    // clean up panel from previous calls.
                    dataPanel.removeAllChildren();

                    for each (var table:Object in event.result.Tables)
                    {
                        displayTable(table);
                    }

                    // Alternatively, if a table's name is known beforehand,
                    // it can be accessed using this syntax:
                    var namedTable:Object = event.result.Tables.Customers;
                    //displayTable(namedTable);
                }
            }

            private function displayTable(tbl:Object):void {
                var dg:DataGrid = new DataGrid();
                dataPanel.addChild(dg);
                // Each table object from the "Tables" map contains two properties:
                // "Columns" and "Rows". "Rows" is where the data is, so we can set
                // that as the dataProvider for a DataGrid.
                dg.dataProvider = tbl.Rows;
            }

            private function onFault(event:FaultEvent):void {
                Alert.show(event.fault.toString());
            }
        ]]>
    </mx:Script>

</mx:Application>

次の例は、Flex アプリケーションによって呼び出されるバックエンド Web サービスの実装である .NET C# クラスを示します。このクラスは、Microsoft SQL Server Northwind サンプルデータベースを使用しています。

:

<%@ WebService Language="C#" Class="CustomerList" %>
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Services.Description;
using System.Data;
using System.Data.SqlClient;
using System;

public class CustomerList : WebService {
    [WebMethod]
    public DataTable getSingleDataTable() {
        string cnStr = "[Your_Database_Connection_String]";
        string query = "SELECT TOP 10 * FROM Customers";
        SqlConnection cn = new SqlConnection(cnStr);
        cn.Open();
        SqlDataAdapter adpt = new SqlDataAdapter(new SqlCommand(query, cn));
        DataTable dt = new DataTable("Customers");

        adpt.Fill(dt);
        return dt;
    }

    [WebMethod]
    public DataSet getMultiTableDataSet() {
        string cnStr = "[Your_Database_Connection_String]";
        string query1 = "SELECT TOP 10 CustomerID, CompanyName FROM Customers";
        string query2 = "SELECT TOP 10 OrderID, CustomerID, ShipCity,
        ShipCountry FROM Orders";
        SqlConnection cn = new SqlConnection(cnStr);
        cn.Open();

        SqlDataAdapter adpt = new SqlDataAdapter(new SqlCommand(query1, cn));
        DataSet ds = new DataSet("TwoTableDataSet");
        adpt.Fill(ds, "Customers");

        adpt.SelectCommand = new SqlCommand(query2, cn);
        adpt.Fill(ds, "Orders");

        return ds;
    }
}

 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート