Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Tip: Send multiple Web services requests from XForms

Submit a request and then use the response as the basis for a second request.

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:  A typical HTML form only lets you submit to one URL at a time, which makes it difficult to retrieve information from multiple Web services. This tip shows you how to use XForms to solve that problem by using multiple submissions from a single form.

View more content in this series

Date:  03 Sep 2004
Level:  Intermediate

Activity:  10923 views
Comments:  

Unlike traditional HTML forms, which are typically designed to either get information from or give information to the user, Web services are ultimately designed to provide information to an application; the user is almost an afterthought. This means that while it's generally sufficient to submit an HTML form to a single location and get a response, you often need to submit a request to a Web service and then use the response as the basis for a second request.

In this tip, you'll create an XForms form that provides information on a series of temperature sensors. The form takes a sensor identifier and submits it to a Web service that returns the zip code for that sensor. The form then automatically submits the zip code to a second service that provides the ambient temperature at the location that corresponds to that zip code. This tip assumes that you are generally familiar with XForms and that you have the FormsPlayer XForms client installed. (See the Resources for more information.)

The basic request form

Start by creating the basic form (shown in Listing 1), into which the user enters a sensor ID:


Listing 1. The 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: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="sensorInstance">

             <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:getZip xmlns:ns1="urn:example-sensorZip" 
                      SOAP-ENV:encodingStyle=
                             "http://schemas.xmlsoap.org/soap/encoding/"> 
                      <sensorId xsi:type="xsd:string"></sensorId> 
                   </ns1:getZip> 
                </SOAP-ENV:Body> 
             </SOAP-ENV:Envelope> 

         </xforms:instance>

      </xforms:model>

      <xforms:input ref="instance('sensorInstance')//sensorId">
          <xforms:label>Sensor ID: </xforms:label>
          <xforms:hint>Enter the ID for the sensor whose ambient 
                temperature you want to check.</xforms:hint>
      </xforms:input>

</body>
</html>

Here you have a simple form that enables the user to enter a value, as you can see in Figure 1. That value represents the contents of the sensorId element in the sensorInstance instance. The sensorInstance just happens to be in the form of a SOAP request, which you can then send to a Web service to get a response.


Figure 1: The basic form
The basic form

Submitting to the first service

The first part of the form takes the sensor ID and submits it to a Web service that returns a zip code. To make that happen, you have to add a submission element and a trigger that sends it, as shown in Listing 2.


Listing 2. Submitting the form
...
    <xforms:model id="WeatherService">

       <xforms:instance id="sensorInstance">

             <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:getZip xmlns:ns1="urn:example-sensorZip" 
                   SOAP-ENV:encodingStyle=
                         "http://schemas.xmlsoap.org/soap/encoding/"> 
                   <sensorId xsi:type="xsd:string"></sensorId> 
                </ns1:getZip> 
              </SOAP-ENV:Body> 
             </SOAP-ENV:Envelope> 

       </xforms:instance>

       <xforms:submission id="getzip"
        method="text-xml-post"
        replace="instance"
        ref="instance('sensorInstance')"
        action="http://www.nicholaschase.com/sensors/getZipService.php"
       />

      </xforms:model>

<xforms:switch id="switch1">
  <xforms:case id="requestGUI">

      <xforms:input ref="instance('sensorInstance')//sensorId">
          <xforms:label>Sensor ID: </xforms:label>
          <xforms:hint>Enter the ID for the sensor whose ambient 
                temperature you want to check.</xforms:hint>
      </xforms:input>

      <xforms:trigger style="display:block">
          <xforms:label>Get sensor ambient temperature</xforms:label>
          <xforms:action ev:event="DOMActivate">
              <xforms:send submission="getzip" /> 
              <xforms:toggle case="responseGUI" />
          </xforms:action>
      </xforms:trigger>

  </xforms:case>

  <xforms:case id="responseGUI">

       <xforms:output ref="instance('sensorInstance')//return">
          <xforms:label>Sensor zip code:</xforms:label>
       </xforms:output>

  </xforms:case>
</xforms:switch>

</body>
</html>

When you click the trigger button, two things happen. First, the browser sends the getzip submission. This submission is defined in the model using the submission element, which determines which data gets submitted and where it goes. In this case, you're sending the sensorInstance data to a service, which returns a SOAP message with the response. The actual zip code is in the return element.

After sending the submission, the form changes cases from the requestGUI, which shows the original form, to the responseGUI, which shows the returned data (see Figure 2).


Figure 2: The initial response
The initial response

The second submission

Now that you have the zip code, you have to find a way to send it to the weather service. Start by creating an instance to submit to that service, as shown in Listing 3:


Listing 3. Add the second instance
...
  <xforms:model id="WeatherService">

    <xforms:instance id="sensorInstance">

        <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:getZip xmlns:ns1="urn:example-sensorZip" 
                 SOAP-ENV:encodingStyle=
                        "http://schemas.xmlsoap.org/soap/encoding/"> 
                 <sensorId xsi:type="xsd:string"></sensorId> 
              </ns1:getZip> 
           </SOAP-ENV:Body> 
        </SOAP-ENV:Envelope> 

     </xforms:instance>

     <xforms:instance id="weatherInstance">

        <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"></zipcode> 
              </ns1:getTemp> 
           </SOAP-ENV:Body> 
        </SOAP-ENV:Envelope> 

     </xforms:instance>

     <xforms:submission id="getzip"
         method="text-xml-post"
         replace="instance"
         ref="instance('sensorInstance')"
         action="http://www.nicholaschase.com/sensors/getZipService.php"
        />

     <xforms:submission id="getweather"
         method="text-xml-post"
         replace="instance"
         ref="instance('weatherInstance')"
         action="http://services.xmethods.net:80/soap/servlet/rpcrouter"
        />

    </xforms:model>
...

The overall idea here is the same as what you've done so far: Create an instance that looks like a Web service request and then send it to a Web service as defined in the submission element. All you need to do now is to find a way to get the zip code returned by the first submission into the second instance before submitting the second instance. Fortunately, you can do that using the setvalue element:


Listing 4. Linking the two submissions
...
         <xforms:submission id="getweather"
             method="text-xml-post"
             replace="instance"
             ref="instance('weatherInstance')"
             action="http://services.xmethods.net:80/soap/servlet/rpcrouter"
            />

      </xforms:model>

<xforms:switch id="switch1">
  <xforms:case id="requestGUI">

      <xforms:input ref="instance('sensorInstance')//sensorId">
          <xforms:label>Sensor ID: </xforms:label>
          <xforms:hint>Enter the ID for the sensor whose ambient 
                temperature you want to check.</xforms:hint>
      </xforms:input>

      <xforms:trigger style="display:block">
        <xforms:label>Get sensor ambient temperature</xforms:label>
        <xforms:action ev:event="DOMActivate">
          <xforms:send submission="getzip" /> 
          <xforms:setvalue value="instance('sensorInstance')//return" 
                         ref="instance('weatherInstance')//zipcode"/> 
          <xforms:send submission="getweather" /> 
          <xforms:toggle case="responseGUI" />
        </xforms:action>
      </xforms:trigger>

   </xforms:case>

   <xforms:case id="responseGUI">

       <xforms:output ref="instance('sensorInstance')//return">
          <xforms:label>Sensor zip code:</xforms:label>
       </xforms:output>
       <br />
       <xforms:output ref="instance('weatherInstance')//return">
          <xforms:label>Ambient sensor temperature:</xforms:label>
       </xforms:output>

   </xforms:case>
</xforms:switch>

</body>
</html>

If you look at the trigger, you'll realize that you've simply added more actions for the browser to perform. After submitting the first request, the sensorInstance instance will have a return element that holds the desired zip code. Using the setvalue element, you copy that value to the weatherInstance instance, which you subsequently submit. The results can then be shown in the page, as seen in Figure 3.


Figure 3. The final results
The final results

Summary

XForms is designed to separate the process of displaying data from the process of manipulating it, so it is very well suited to performing multiple submissions with a single request. This process involves creating an instance for each service, with each consisting of a SOAP request for that particular service. When the user causes an event such as activating a button, you can execute any number of actions, and because each instance can have its own submission, you can simply submit each instance in turn, moving data between instances using the setvalue element.


Resources

About the author

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.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, SOA and Web services
ArticleID=15082
ArticleTitle=Tip: Send multiple Web services requests from XForms
publish-date=09032004
author1-email=nicholas@nicholaschase.com
author1-email-cc=dwxed@us.ibm.com