XForms/Web service

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Web services can be called directly from an XForms application using the submission element in the model.

Connecting a web service to an Event[edit | edit source]

To call a web service you first need to "wire it" up to an event. For example this can be a "submit" button at the end of a form.

The submit element is usually in the presentation (inside the body tag) and is wired to a <submission> element in the model.

 <head>
   <xf:model id="my-model">
      <xf:submission id="<b>callWebService</b>">
            <...>
      </xf:submission>
   </xf:model>
 </head>
 <body>
   <xf:submit submission="<b>callWebService</b>">
      <xf:label>Press Button to Call a Web Service</xf:label>
   </xf:submit>
 </body>
</<syntaxhighlight>

== Sample Program ==
The program consists of several parts.

In the model:
# The SOAP submission instance
# The submission
# The SOAP response placeholder

=== SOAP input message ===
Here is an example of the input SOAP message
<pre>
 <!-- What we send to the web service -->
 <xf:instance id="submit-instance" xmlns="http://schemas.xmlsoap.org/soap/envelope/">
   <soap-env:Envelope>
      <soap-env:Body>
          <m:test xmlns:m="http://www.example.com/web-services/my-operation"
            SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
              <string xsi:type="xsd:string">Hello world!</string>
          </m:test>
       </soap-env:Body>
    </soap-env:Envelope>
 </xf:instance>
 <!-- /env:Envelope/env:Body/m:ecrvTestResponse/result -->
</pre>

=== Putting the SOAP Results in an Instance ===
When the web service returns you need to put the returning SOAP response in an instance.  We create another instance in the model and we also need to give it an identifier.  In this case I called it "results-instance".

<syntaxhighlight lang="xml">
 <xf:instance id="results-instance" xmlns="">
    <env:Envelope/> 
 </xf:instance>
 <xf:bind id="results-bind" nodeset="instance('results-instance')/env:Envelope"/>

This is just a temporary storage area that the results will be inserted into.

The XForms submission Statement[edit | edit source]

 <xf:submission id="send-to-dor-document-web-service"
    action="<nowiki>http://www.example.com/web-service/my-web-service</nowiki>" 
    method="post" 
    mediatype="text/xml"
    ref="instance('submit-instance')"
    replace="instance" 
    instance="results-instance">
    <xf:toggle case="case-busy" ev:event="xforms-submit" />
    <xf:toggle case="case-submit-error" ev:event="xforms-submit-error" />
    <xf:toggle case="case-done" ev:event="xforms-submit-done" />         
 </xf:submission>

There are few things to note. The action attribute is the URL of the connection point of the web service. The operation you call is not included in the URL.

The method (get, put or post) in this case is a post.

Mediatype[edit | edit source]

XForms is a rich application development standard. So by default the HTTP transactions used by XForms use a mediatype for XML application that includes binary files and binary attachments. So by default, XForms sends an HTTP command with the following in it:

 mediatype="application/xml"

However most simple web services do not support binary. The mediatype for ASCII text (without binary) is just:

 mediatype="text/xml"

So if you will also be sending binary files you will need to add a mediatype attribute to to your submission:

 <xf:submission mediatype="application/xml"...

Debugging Response Documents[edit | edit source]

You can also replace the entire document with the XML result (the option is replace="all") or you can just have it replace an instance.

The last three <toggle> statements are for displaying results.

A style sheet[edit | edit source]

This makes the error messages red and the correct responses green.

 <style type="text/css">
     @namespace xf url("http://www.w3.org/2002/xforms");
     body {font-family: Helvetica, sans-serif}
     .code {font-family: Courier New, fixed-width; font-weight:bold;}
     .error-message {font-weight:bold; color: red}
     .ok {font-weight:bold; color: green}
     xf|output {font-weight:bold; font-size: 16pt}
  </style>

The Presentation[edit | edit source]

Here is the actual body of the XForms document. It has a single button that calls the web service.

 <body>
    <h1>Web Service Demo</h1>
         <p>Note: With some browsers (FireFox) you must add the appropriate
         hosts to your XForms "white list" for this application to run.
         With FireFox see Tools/Options/Content tab.</p>
     <xf:submit submission="call-web-service">
         <xf:label>Call Web Service</xf:label>
     </xf:submit>  
     <hr/>
     <p>Current form status:</p>
     <xf:switch>
        <xf:case id="case-start">Status: Ready to call web service.</xf:case>
        <xf:case id="case-busy">Waiting for response...please stand by...</xf:case>
        <xf:case id="case-submit-error">
           <p class="error-message">Submission error. Did you remember to allow XForms to submit data to other domains?</p>
        </xf:case>
        <xf:case id="case-done">
           <p class="ok">Results returned successfully</p>
           <xf:group model="my-model">
             <xf:output ref="instance('results-instance')/env:Body/m:my-results/result">
               <xf:label>Return value: </xf:label>
             </xf:output>
           </xf:group>
         </xf:case>
      </xf:switch>
   </body>

Discussion[edit | edit source]

The presentation conditionally displays the error messages using a switch/case section. The toggle elements are each triggered by the appropriate event.

You can also put a spinning GIF icon in the section to get an animation for a response from the server.


Next Page: Stock Quote | Previous Page: Search flickr
Home: XForms