Skip to main content

Tip: Use XForms to send and receive Web services messages

Leverage the power of XML

Nicholas Chase (nicholas@nicholaschase.com), President, Chase and Chase, Inc.
Photo of Nicholas Chase
Nicholas Chase, a Studio B author, has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, and an Oracle instructor. More recently, he was the Chief Technology Officer of an interactive communications firm in Clearwater, Florida, USA, and is the author of several books on Web development, including XML Primer Plus (Sams). He's currently trying to buy a farm so he and his wife can raise alpacas and chickens. He loves to hear from readers and can be reached at: nicholas@nicholaschase.com.

Summary:  One of the great strengths of XForms is the fact that an XForms client can send its data as XML, and that it receives XML in return. This capability can be exceptionally useful in the field of Web services, where that's exactly what gets sent and received: XML messages. In this tip, the author looks at how to use an XForms browser as a Web services client, sending a SOAP request and displaying the results directly in the browser.

View more content in this series

Date:  24 Jun 2004
Level:  Intermediate
Activity:  3989 views

This tip assumes a basic familiarity with XForms and with Web services. It uses the FormsPlayer plug-in for Internet Explorer (see Resources to download it).

The Web service

In this tip, I'm going to show you how to create an XForms form that sends a request to a Web service and then displays the results. To keep things simple, I'm going to use the ubiquitous weather example, sending a ZIP code and receiving the current temperature. The actual Web service is provided by XMethods.net (see Resources).

The initial request is just a SOAP message, such as:


Listing 1. Initial SOAP request
<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>

You'll use the XForms form to provide a value for the zipcode element. When you submit it to the service, you'll get a response such as:


Listing 2. Response
<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>

You'll also use the form to retrieve the return value and display it.


The basic XForms form

Start by creating the basic form. An XForms form consists of a model and controls. The model includes information such as the instance, which represents the data to be displayed and submitted, and the submission, which includes information on where and how to send the data:


Listing 3. A basic XForms form
<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>

First, tell Internet Explorer to load the FormsPlayer object. If it's not loaded, the browser displays the contents of the tag, telling the user to download and install it.

Next you have the model, which includes the instance and the submission. The instance is not just the data to be displayed; it's also the data that will eventually be submitted, so it's identical to the SOAP request presented earlier in Listing 1. You'll get a closer look at the submission itself when you actually submit the data.

In the meantime, you need to actually create the form:


Listing 4. Create the form
...
   <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>


Figure 1: The simple text control
The simple text control

When the user changes the value in this control, it changes the corresponding node of the XML contained in the instance. So if you were to change the value in that field to, say, 10314, the instance document would look like this in memory:


Listing 5. Instance document
<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> 

It is this document that gets submitted to the service. Before you get that far, however, you need to look at the state of the form.


Changing states

When you submit the form, you will actually replace the instance document with a second instance document that has a different structure, so in order to display information from it, you will need controls based on that structure instead of the original one. You can't, however, include both of these controls on the page at the same time, because one of them will always refer to a nonexistent node, causing an error. To get around this problem, you need to create a situation in which only one set appears at a time. You can do that with a switch:


Listing 6. Add a switch
...
   </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>

Here there are two cases. The first is displayed by default. To this case you add a trigger, or button, that activates when you click it, as in Figure 2.


Figure 2. Add a trigger
Add a trigger

When it does, it executes everything in the action element, which in this case is to toggle the case to the responseGUI state. This tells the browser to display only that case, as in Figure 3:


Figure 3. The results case
The results case

Using this form, the user can toggle back and forth by clicking the buttons. Now you need to add the form submission.


Submitting the form

Of course, the form isn't much good to you this way. What you ultimately want is to switch to the results case after you submit the form. You can do that by adding the submission to the action:


Listing 7. Add the submission to the action
...
         <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>
...

This simply tells the browser to execute the submission getweather when the user clicks the button. Now, when you created the submission, you added some information to it:


Listing 8. Specify the submission as an XML post
...
      <xforms:submission id="getweather"
           method="text-xml-post"
           replace="instance"
           action="http://services.xmethods.net:80/soap/servlet/rpcrouter"
               />
...

This submission specifies that you're submitting it as an XML post, which is perfect for a SOAP message, and that you want to replace the instance. This way, when it comes back, the instance looks something like Listing 9:


Listing 9. Returned instance
<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> 

To see the results, you need to retrieve them from within the resultGUI case:


Listing 10. Retrieve the results
  <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>
...

This way, when you submit the form, you get the resulting temperature, as in Figure 4.


Figure 4. The resulting page
The resulting page

Summary

Because an XForms form sends and receives XML documents, it makes an excellent Web services client. In this tip, I showed you the basic process of using an XForms form to request information from a Web service. The process looked like this:

  1. The browser displays information from the instance document, which is structured as a SOAP request.
  2. The browser sends the instance document (including the ZIP code) to the Web service.
  3. The Web service sends a response (including the temperature) to the browser, which uses it to replace the original instance document.
  4. The browser switches to a second set of controls, which display the information returned by the Web service.

Resources

About the author

Photo of Nicholas Chase

Nicholas Chase, a Studio B author, has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, and an Oracle instructor. More recently, he was the Chief Technology Officer of an interactive communications firm in Clearwater, Florida, USA, and is the author of several books on Web development, including XML Primer Plus (Sams). He's currently trying to buy a farm so he and his wife can raise alpacas and chickens. He loves to hear from readers and can be reached at: nicholas@nicholaschase.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, SOA and Web services
ArticleID=11933
ArticleTitle=Tip: Use XForms to send and receive Web services messages
publish-date=06242004
author1-email=nicholas@nicholaschase.com
author1-email-cc=dwxed@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers