これまでのヒントでは、XFormsフォームがいかに容易にWebサービス・リクエストを送信でき、またレスポンスを受信できるかを学びましたが、どの場合にも、全てのインスタンスをWebサービスに対して送信していました。しかしながらこれは、必ずしも皆さんの意向に合致するとは限りません。例えばSOAPメッセージは、関連したデータを含む、より大きなインスタンス文書の一部かも知れません。今回のヒントでは、単なるSOAPメッセージ以上のものを含むインスタンスを中心にXFormsフォームを作成し、そして送信指示に対してはSOAPメッセージのみを送信する方法について説明します。このヒントでは、XFormsの一般的な概念を理解していること、またFormsPlayer XFormsクライアントがインストールしてあることを前提としています(詳しい情報は、参考文献を見てください)。
まず、基本的なフォームを作るところから始めましょう(リスト1)。
リスト1. 基本的なフォーム
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>
<head>
<title>XForms and Web Services</title>
</head>
<body>
<object id="FormsPlayer" classid="CLSID:4D0ABA11-C5F0-4478-991A-375C4B648F58">
<b>FormsPlayer has not loaded. Please check your installation.</b>
</object>
<?import namespace="xforms" implementation="#FormsPlayer" ?>
<xforms:model id="WeatherService">
<xforms:instance id="weatherInstance" >
<data>
<employees>
<emp id="1">
<name>Nick</name>
<zip>10314</zip>
</emp>
<emp id="2">
<name>Troy</name>
<zip>90210</zip>
</emp>
<emp id="3">
<name>Bob</name>
<zip>34652</zip>
</emp>
</employees>
<soapmessage>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTemp xmlns:ns1="urn:xmethods-Temperature"
SOAP-ENV:encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/">
<zipcode xsi:type="xsd:string"></zipcode>
</ns1:getTemp>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</soapmessage>
</data>
</xforms:instance>
</xforms:model>
</body>
</html>
|
このインスタンスには、employeesデータ(従業員情報)と、(soapmessage要素中にある)SOAPメッセージという2つの基本的な部分があります。皆さんは、これを送信する前に、employeesデータを使ってSOAPメッセージに情報を代入するでしょう。そうするためには、リスト2に示すような各従業員の選択肢を提供するためのselect1コントロールを追加します。
リスト2. select1メニューを追加する
<xforms:select1 appearance="minimal" ref="instance('weatherInstance')//zipcode">
<xforms:label>Choose Employee</xforms:label>
<xforms:itemset nodeset="instance('weatherInstance')//emp">
<xforms:label ref="name"/>
<xforms:value ref="zip"/>
</xforms:itemset>
</xforms:select1>
</body>
</html>
|
このコントロールは、emp要素のそれぞれを繰り返し取得し、図1のようなドロップダウン・メニューを作成します。
図1. 基本的なデータ・コントロール
select1要素のref属性がSOAPメッセージのzipcode要素を指し示すように設定してあるので、ドロップダウン・メニューを変更するだけで、Webサービスのリクエストに適切な値が追加されます。
送信指示に進む前に、フォームの残り部分を書込みます。
このプロジェクトの目標は、SOAPメッセージを送信し、その次にSOAPレスポンスを取得し、その結果を表示することです。これを行うためには、送信指示用のトリガー・ボタンと、返送されたデータを読み取る機能を追加する必要があります。これをリスト3に示します。
リスト3. フォーム自体の残りの部分を追加する
...
</data>
</xforms:instance>
</xforms:model>
<xforms:switch id="switch1">
<xforms:case id="requestGUI">
<xforms:select1 appearance="minimal" ref="instance('weatherInstance')//zipcode">
<xforms:label>Choose Employee</xforms:label>
<xforms:itemset nodeset="instance('weatherInstance')//emp">
<xforms:label ref="name"/>
<xforms:value ref="zip"/>
</xforms:itemset>
</xforms:select1>
<xforms:trigger style="display:block">
<xforms:label>Get sensor ambient temperature</xforms:label>
<xforms:action ev:event="DOMActivate">
<xforms:send submission="getweather" />
<xforms:toggle case="responseGUI" />
</xforms:action>
</xforms:trigger>
</xforms:case>
<xforms:case id="responseGUI">
<xforms:output ref="instance('weatherInstance')//return">
<xforms:label>Employee local temperature:</xforms:label>
</xforms:output>
</xforms:case>
</xforms:switch>
</body>
</html>
|
コントロールにデータを提供するインスタンスが送信指示の前と後で異なるので、ここではフォームを2つの場合に分けています。まず、従業員データのコントロールとtriggerボタンを含む、最初の場合から始めます。ユーザがトリガーをクリックすると、ブラウザはgetweatherの送信指示(これを次に作ります)を送信し、responseGUIの場合に変わり、そして新しい構造からデータを探します。一旦responseGUIの場合に移行すると、ブラウザはreturn要素の中にある、温度を表示します。
今度は実際の送信指示(submission)を作成しなければなりません。
フォームを送信するためには、submission要素を作る必要があります。このsubmission要素は、単にデータがどこに行くべきかを(action属性によって)指定するだけではなく、どんなデータが行くべきなのか、そして戻ってくるデータをどうするべきなのかも指定します。例えば、リスト4に示す単純なsubmission要素を見てください。
リスト4. 単純なsubmission要素
<xforms:submission method="text-xml-post"
action="http://services.xmethods.net:80/soap/servlet/rpcrouter" />
|
この要素で必要なことはできますが、あまり的確な方法でありません。XFormsクライアント(この場合はブラウザ)は、従来のHTMLフォームに対する場合と同様に、アクションで指定されたURLに全てのインスタンスを送信し、その後で、全ページをレスポンスで置き換えます。しかしこれは、私達が望んでいることとは少し異なります。ここでは、soapmessage要素の内容のみを送信し、レスポンスが返ってきたら、インスタンスのみを入れ換えて、フォームの残り部分はそのままにしておきたいのです。これらはすべて、submission要素の上で指定できます。これをリスト5に示します。
リスト5. Submission要素
...
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</soapmessage>
</data>
</xforms:instance>
<xforms:submission id="getweather" method="text-xml-post"
ref="instance('weatherInstance')//soapmessage/*"
replace="instance"
action="http://services.xmethods.net:80/soap/servlet/rpcrouter"
/>
</xforms:model>
|
このsubmission要素は、soapmessage要素の内容のみを送信したいこと、そしてレスポンスが返ってきたら、文書全体ではなくインスタンスのみを入れ換えたいのだ、ということを指定しています。
ここで、送信しているのはインスタンスの一部のみですが、Webサービスがレスポンスを返す時には、そのレスポンスがインスタンスの全体を置き換えてしまうことに注意してください(これは一般的に、やり直しの利かないことなのです)。これを防ぐために、返送されてきたデータが何も置き換えないように、replace="none" を使って明示することができます。たたしこれができるのは、送信指示自体が重要で、レスポンスが重要ではない場合のみです。
XFormsフォームを使うことによって、SOAPメッセージを含むインスタンスを作ることができますが、インスタンスには同様に他のデータを含むこともできます。例えば今回の場合では、実際のSOAPメッセージに情報を代入するために、(インスタンス中の)他の場所にあるデータを使うフォームを作成しました。これがうまく動作するようにするためには、実際に送信したいインスタンス部分を指定するsubmission要素を作ります。またこのsubmission要素を使って、返ってきたデータをどう扱うべきかを明示することもできます。
- W3CのXForms勧告 または、チュートリアル「Understanding XForms」(developerWorks, 2002年12月)を読んでください。
- この記事の解説で使われているFormsPlayer plug-in for Internet Explorer をダウンロードしてください。
- Webサービスのリクエスト送信について、さらに学ぶために「XFormsを使ってWebサービス・メッセージを送受信する」(developerWorks, 2004年6月)を読んでください。
- XFormsとWebサービスでの複数インスタンスの使い方について、「第2のインスタンスを送信するXFormsフォームを作る」(developerWorks, 2004年7月)を読んでください。
- developerWorksのXMLゾーン とSOA and web servicesゾーン には、他にも幅広い話題の記事やコラム、チュートリアル、ヒントなどが豊富に用意されています。
- developerWorksのDeveloper Bookstore には、XML関連の書籍が豊富に取り揃えられていますので、ぜひご覧ください。
