ShowTable of Contents
New in IBM Forms Designer 4.0 is the Web services wizard, with which you can easily consume Web services from your form by choosing which Web service operation you wish to call and then dragging and dropping, to map elements from the Web service to items in your form. The Web service wizard does the rest, building the appropriate logic into the form so that, at run time, the Web service is consumed by the form.
Say you've gone through the process of mapping the form data to the Web service input and output, and then saved and published your form. At some point in the future, the Web service changes and you need to update your form to be able to use the new version of the Web service. This article describes some basic steps for doing this without having to redo all the mapping that you did initially.
Understanding the Web services wizard
The first approach to update your form is simply to remove the existing Web service, add the new Web service, and then re-map everything. If this is considered to be a small task, then it's likely the easiest way to do it.
However, if your form is not small, and you had to map many fields into and out of the Web service, and you don't want to do that again (or every time your Web service changes in the future), then you'll need to learn a bit about how the Web services wizard works, and what is actually built into the form by the wizard.
The first thing you must realize is that everything that the Web services wizard does is stored in the form and is expressed as XFDL and XForms. There is no special code that performs Web-service-only operations.
There are three main areas of interest we need to consider when learning about the logic that the Web services wizard builds: The design-time information, the schema, and the run-time logic.
The design-time information stores data about:
- What parts of the Web service should be mapped to what items in the form
- How the Web service is supposed to be triggered
- What needs to happen after the Web service is done
- How to respond to errors
This information is used by the Web services wizard to determine what to display in the Web Services drawer in the outline view and is used to generate the appropriate run-time logic.
The run-time logic that the Web service wizard adds to the form actually carries out what was specified by the design-time information. Mainly, it builds two instances (that are viewable only in the source view):
operationName.input. This is an XML instance that is posted to the Web service, also referred to as the SOAP request message.
operationName.output. This is an XML instance that is populated with the response from the Web service, also referred to as the SOAP response message.
The xforms:submission is a way for a form to send XML over HTTP to some backend system. It can accept XML back and put that XML into the form. This is the way the form "talks" to the Web service, as Web services are simply a certain type of XML over HTTP.
The Web services wizard builds this xforms:submission that responds to three events:
- xforms-submit: Actions to run before the xforms:submission occurs (in this case before the Web service is called). Here you'll find xforms actions that copy the data from the form into the operationName.input instance.
- xforms-submit-done: Actions to run after the xforms:submission completes. Here you'll find xforms actions that copy the data from the operationName.output instance back into the form.
- xforms-submit-error: Actions to run if the xforms:submission received an error from the Web service.
All this run-time logic is generated by the Web services wizard. If you manually change any of this logic in the source view, then it might be overwritten when using the Web service drawer in the outline view. Each time a change is made in the Web Services drawer, it regenerates the associated run-time logic. We'll take advantage of this fact later.
The schema information is pulled from the WSDL and stored into the form. Note that the WSDL is not stored in the form, just in the schema. This schema is used by the wizard to generate the input and output instances and to determine what type of form items should be created; for example, the wizard creates a checkbox for a Boolean type, and a table for a repeating element.
If you look in the source view of a form after a Web service has been added to it, you'll find three subject areas in different places in the form:
(1) The design time information, stored in a <designer:wsConn> element:
where there can be many <designer:wsConn> elements inside the <designer:wsConns> element (one for each Web service being consumed).
(2) The schema, stored in a <designer:wsSchema> element:
where there can be many <designer:wsSchema> elements inside the <designer:wsSchemas> element (one for each Web service being consumed).
(3) The run-time logic, which is found in a <xforms:submission> and also in the form item that is associated with how the Web service is to be triggered. You'll see that the form item will have a designer:genid attribute.
For example, if the Web service is to be triggered when a button is clicked, you'll find something like this:
<xforms:action designer:genid="/wsConn_getAccounts1/trigger_PAGE1.getAccounts1_onClick" ev:event="DOMActivate">
so in this case, the <xforms:submission> with id="getAccounts1" will be called when this button is clicked.
In a form, there can be many Web services being consumed, so you might find many <xforms:submission>, <designer:wsConn>, and <designer:wsSchema> elements.
The <designer:wsConn> and <designer:wsSchema> elements will always be in a parent <designer:wsConn> and <designer:wsSchema> parent element, but the <xforms:submission> might be anywhere in the xforms:model, so make sure to work with the correct one.
The <designer:wsConn> and <designer:wsSchema> elements are visible only in the source view of the Designer, but you should see the <xforms:submission> in the XForms view.
Updating your form
Now that we understand what the Web services wizard adds to the form, we can use that to make it much easier to update a form to use a new version of a Web service it already consumes.
The basic steps to update your form are as follows:
- Back up your <designer:wsConn> by going into the source view, finding your existing <designer:wsConn>, and copying the entire element into a separate text file (or you can paste it into the form as a comment).
- Remove the existing Web service from the form by going into the Web services drawer, right-clicking on the Web service, and choosing "Delete Web Service". At this point the associated input and output instances, <xforms:submission>, <designer:wsConn>, and <designer:wsSchema> will be removed from the form.
- Add the new Web service to the form, using the Web services wizard. Do not generate a UI.
- After this is done, you should have new input and output instances (containing the new structure) and new <xforms:submission>, <designer:wsConn>, and <designer:wsSchema> elements.
- In the Web Service drawer, you should now see the new structure of input and output messages, but nothing is mapped to your form.
4. Remove the new <designer:wsConn> by returning to the source view, finding the new <designer:wsConn> element, and deleting it.
5. Restore your old <designer:wsConn>:
- Go into the source view and copy your backed-up <designer:wsConn> back into place.
- Return to the design view; you should see your old mapping instructions in the Web service drawer.
6. Make the wizard regenerate the run-time logic, though at this point the run-time logic has not been regenerated according to what was specified in your old <designer:wsConn>, so we must make it regenerate that. The easiest way to do this is to make a change in the Web Services drawer; specifically, we need to do this in the Input, Output, and Triggers sections:
- In the Input section, select one of the inputs in the Web service. This highlights the associated item in the form; remember this. Then delete the mapping and recreate it. This causes the associated run-time logic for this mapping and ALL the rest of the Input mappings to be regenerated.
- Perform the same steps for the Output and Triggers sections, deleting and recreating one mapping in each section.
- In the After Done and When Fails sections, simply click the Edit button of that section in the Web services drawer, and then click OK in the following dialog box. This regenerates the associated run-time logic.
7. Update the form to use the new parts of the Web service:
- Some changes have been made to the Web service (after all, this is why we're updating the form), so depending on that change, either remove any items from the form that no longer have an associated Web service field or create new form items to map to the new Web services field.
After you perform the above steps several times, it takes only about a minute to perform, and hopefully you'll find it a very easy way to update your forms when your Web services changes.
This article has explained the steps for updating a form when a Web service that it consumes has changed.
About the author
Eric Dunn is a Software Developer based at IBM's Victoria, BC, facility in Canada and currently works as the Special Engagements Lead for IBM Forms. You can reach him at firstname.lastname@example.org