IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML  >

技巧: 使用 XForms 发送和接收 Web 服务消息

利用 XML 的强大功能

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 中级

Nicholas Chase (nicholas@nicholaschase.com), 总裁, Chase & Chase, Inc.

2004 年 7 月 01 日

XForms 的强大之处在于 XForms 客户机可以使用 XML 发送它的数据,然后接收返回的 XML。这种能力可能在 Web 服务领域中特别有用,因为在那里发送和接收的就是 XML:XML 消息。这篇技巧中我将说明如何使用 XForms 浏览器作为 Web 服务客户,发送 SOAP 请求,然后直接在浏览器中显示结果。

本篇技巧假设您对 XForms 和 Web 服务有基本的了解,使用了 Internet Explorer 的 FormsPlayer 插件(请参阅 参考资料以便下载它)。

Web 服务

这篇技巧中,我将说明如何创建向 Web 服务发送请求然后显示结果的 XForms。为了简单起见,我将使用普遍存在的天气的例子,发送一个 ZIP 代码并接收当前的气温。实际的 Web 服务由 Xmethods.net 提供(请参阅 参考资料)。

初始请求只是一个 SOAP 消息,比如:


清单 1. 初始 SOAP 请求
<SOAP-ENV:Envelope
       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
       xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
       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">02134</zipcode>
      </ns1:getTemp>
   </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

您将使用 XForms 表单为 zipcode 元素提供数据。提交给 Web 服务后将得到如下所示的响应:


清单 2. 响应
<SOAP-ENV:Envelope
       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
       xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
       xmlns:xsd="http://www.w3.org/1999/XMLSchema">
   <SOAP-ENV:Body>
      <ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature" 
           SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <return xsi:type="xsd:int">86</return>
      </ns1:getTempResponse>
   </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

还要使用该表单接收返回值并显示。





回页首


基本的 XForms 表单

首先来创建一个基本的表单。XForms 表单由模型和控件组成。模型包括 instancesubmission 这样的信息,前者表示要显示和提交的数据,后者包括向何处发送以及如何发送数据的信息:


清单 3. 基本的 XForms 表单
<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:xsi="http://www.w3.org/1999/XMLSchema-instance"
   xmlns:ev="http://www.w3.org/2001/xml-events"
   xmlns:ns1="urn:xmethods-Temperature"
   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="messages">
           <SOAP-ENV:Envelope 
                xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
                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">02134</zipcode> 
                 </ns1:getTemp> 
              </SOAP-ENV:Body> 
           </SOAP-ENV:Envelope> 
         </xforms:instance>
         <xforms:submission id="getweather"
             method="text-xml-post"
             replace="instance"
             action="http://services.xmethods.net:80/soap/servlet/rpcrouter"
             />
      </xforms:model>
</body>
</html>

首先告诉 Internet Explorer 加载 FormsPlayer 对象。如果没有载入,浏览器就显示标签中的内容,告诉用户下载并安装该插件。

接下来是 model ,其中包括 instancesubmissioninstance 不仅仅是要显示的数据,同时也是最终将提交的数据,因此就相当于前面 清单 1 中所示的 SOAP 请求。 在真正提交数据的时候,您将更详细地看到 submission 本身。

同时还需要实际创建该表单:


清单 4. 创建表单
...
   <xforms:model id="WeatherService">
     <xforms:instance id="messages">
       <SOAP-ENV:Envelope 
            xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
            xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
            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">02134</zipcode> 
             </ns1:getTemp> 
          </SOAP-ENV:Body> 
       </SOAP-ENV:Envelope> 
     </xforms:instance>
     <xforms:submission id="getweather"
           method="text-xml-post"
           replace="instance"
           action="http://services.xmethods.net:80/soap/servlet/rpcrouter"
           />
   </xforms:model>
   
        <xforms:input ref="instance('messages').//zipcode">
   <xforms:label>Zip code: </xforms:label>
   <xforms:hint>Enter a zip code and submit the form for the current
         temperature in that area.</xforms:hint>
  </xforms:input>
</body>
</html>
      


图 1: 简单文本控件
简单文本控件

如果用户改变控件中的值,它就修改包含在实例中的 XML 的相应节点。比方说如果把字段中的值改为 10314 ,那么实例文档在内存中看起来就是这样:


清单 5. 实例文档
<SOAP-ENV:Envelope 
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
      xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
      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"
        >10314</zipcode>
       </ns1:getTemp> 
   </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 
      

将提交给服务的就是这个文档。但是在进行这一步之前要看一看表单的状态。





回页首


改变状态

在提交表单时,实际上是用具有不同结构的另一个实例文档代替了这个实例文档,因此要显示器中的信息,您就需要适合那种结构的控件而不是原来的控件。但是不能同时在页面中包括这些控件,因为必有一个引用不存在的节点从而造成错误。为了避免这个问题,您需要建立一个条件,根据这个条件每次只显示一组控件。可以使用 switch 来完成:


清单 6. 增加开关
...
   </xforms:model>
   
        <xforms:switch id="switch1">
      <xforms:case id="requestGUI">
         <xforms:input ref=".//zipcode">
            <xforms:label>Zip code: </xforms:label>
            <xforms:hint>Enter a zip code and submit the form for the current
                  temperature in that area.</xforms:hint>
         </xforms:input>
         
        <xforms:trigger style="display:block">
            <xforms:label>Change to results case</xforms:label>
            <xforms:action ev:event="DOMActivate">
               <xforms:toggle case="responseGUI" />
            </xforms:action>
         </xforms:trigger>
      </xforms:case>
      <xforms:case id="responseGUI">
         Results go here.
         <xforms:trigger>
            <xforms:label>Change to request case</xforms:label>
            <xforms:action ev:event="DOMActivate">
               <xforms:toggle case="requestGUI" />
            </xforms:action>
        </xforms:trigger>
     </xforms:case>
 </xforms:switch>
</body>
</html>
      

这里分为两种情况。第一种是默认显示的表单,这里增加了一个 trigger 或者按钮,单击时将会激活,如图 2 所示。


图 2. 增加触发器
增加触发器

激活的时候将执行 action 元素中的所有内容,就本例而言就是切换到 responseGUI 状态。这样就告诉浏览器只显示第二种情况,如图 3 所示:


图 3. 显示结果
显示结果

使用这个表单用户可以单击按钮来回切换。现在需要增加表单提交的功能。





回页首


提交表单

当然这样的表单还不够完善。最终的目标是希望在提交表单值后切换到结果显示。为此可以在动作中增加提交的功能:


清单 7. 在动作中增加提交
...
         <xforms:trigger style="display:block">
            <xforms:label>Get current temperature</xforms:label>
            <xforms:action ev:event="DOMActivate">
               <xforms:send submission="getweather" />
               <xforms:toggle case="responseGUI" />
            </xforms:action>
         </xforms:trigger>
...

这里仅仅告诉浏览器当用户单击该按钮时执行提交 getweather 。创建该提交时还需要增加一些信息:


清单 8. 指定提交为 XML post
...
      <xforms:submission id="getweather"
                   method="text-xml-post"
           replace="instance"
           action="http://services.xmethods.net:80/soap/servlet/rpcrouter"
               />
...
      

该提交规定将其作为 XML post 提交,这正是 SOAP 消息使用的方式,而且您希望替换该实例。这样在返回的时候,该实例看起来类似于清单 9:


清单 9. 返回的实例
<SOAP-ENV:Envelope 
       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/1999/XMLSchema"> 
   <SOAP-ENV:Body> 
      <ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature" 
          SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <return xsi:type="xsd:int"
        >86</return> 
      </ns1:getTempResponse> 
   </SOAP-ENV:Body> 
 </SOAP-ENV:Envelope> 
      

为了看到返回的结果,您需要从 resultGUI 部分进行检索:


清单 10. 检索结果
  <xforms:case id="responseGUI">
    <xforms:output ref="instance('messages')//return" 
            style="width:40ex;display:block;">
      <xforms:label>Current Temperature:</xforms:label>
    </xforms:output>
  </xforms:case>
...

这样当提交该表单时就得到了返回的气温值,如图 4 所示。


图 4. 结果页面
结果页面




回页首


结束语

因为 XForms 表单发送和接收 XML 文档,因此很适合作为 Web 服务客户程序。这篇技巧中,我说明了使用 XForms 表单从 Web 服务请求信息的基本过程。这个过程如下:

  1. 浏览器显示实例文档中的信息,该文档采用 SOAP 请求的结构。
  2. 浏览器向 Web 服务发送该实例文档(包含 ZIP 代码)。
  3. Web 服务向浏览器发送响应(包含气温),后者用响应代替原来的实例文档。
  4. 浏览器切换到第二组控件,显示 Web 服务返回的信息。


参考资料



关于作者

Nicholas Chase 参与了 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa Bay Buccaneers 等公司的网站开发。Nick 曾是一名高中物理教师、放射性废物设备初级管理人员、在线科幻小说杂志编辑、多媒体工程师和 Oracle 讲师。最近,他成为 Site Dynamics Interactive Communications(位于佛罗里达州克利尔沃特市)的首席技术官,而且还是三本有关 Web 开发书籍的作者,包括 Java and XML From Scratch(Que)和即将出版的 Primer Plus XML Programming(Sams)。他乐于听取读者的意见,可以通过 nicholas@nicholaschase.com与他联系。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款