XForms/Web service
Web services can be called directly from an XForms application using the submission
element in the model.
Connecting a web service to an Event
editTo 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
<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
editXForms 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
editYou 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
editThis 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
editHere 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
editThe 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.