In order to understand the content of this lesson, make sure you watched the following lesson:
This lesson gives you the knowledge to help you invoke a web service. This lesson does NOT cover how to create Web Services but provides references to deepen your knowledge about the world of Web Services. This lesson will focus on SOAP-based Web Services.
The Model Weakness
Even if the invocation is running correctly in the current version of the model there's a weakness. The response given by the Web Service is a long string containing an XML Document having a specific structure, but since in the XSD Definition the output is set as string, the model is not able right now to use the structured information. Of course it’s possible to change the model in order to save all the structured information and show something that is more readable to the user.
The XML document retrieved from the Web Service can be broken down, thus identifying all the pieces of data that can be extracted. For instance the "Stock Quote" may become an entity with several attributes such as "Symbol", "Change", "Volume" and so on.
How to Add a Volatile Entity with Scope Session
In order to save these data correctly you need an additional Entity in the Domain Model.
Let's add a "Volatile Entity" with scope session that will store all the pieces of data related to a "Stock Quote". Move to the Domain Model and select the entity object from the toolbar and place it in the workarea. Directly type "Stock Quote" as name. Move to the Properties View to set the "Duration" property of the entity to be "volatile (session scope)".
Now let's add all the attributes for the "Stock Quote", right-click on the entity and choose the command "Edit Entity", this will open the "Edit Entity" dialog. Here you can use the "Add" and "Remove" buttons to configure the attributes for the entity. Add as many attributes as nodes of the XML structure, and choose as type always the "string" type. At the end, press the "OK" button to confirm your choice.
In order to store the Web Service response into this entity also the "Action Definition" model must be changed.
The updated model of the "Action Definition" should look like this. As you can see, in order to be able to save the information in the "Stock Quote" entity it’s necessary to add an operation that is able to transform an input XML Document into another XML Document or into a set of output parameters that can be used by other operations.
The operation to be used is the "Adapter" operation.
The "Adapter" operation is an operation that transforms an XML Document into another XML Document by using a specific transformation algorithm.
The algorithm used must be defined inside a transformation file, which also contains the definition of input and output parameters associated with the operation.
In our example the input parameter is the document containing all the Web Service response, while the output parameters are the single information related to the "Stock Quote", such as "Symbol", "Date", "Time" and so on. The transformation file is a template file written using the "Groovy" language. It has a specific extension that is "*.template". This particular file, which is basically a "Groovy" script, must be placed together with the other scripts inside the "WebContent/WEB-INF" folder of your Web application.
The Transformation File
Skeleton of the Transformation File
The transformation file has a very precise structure, divided into different sections corresponding to different pieces of the algorithm.
This section contains the definition of all the output parameters that must be provided after the "Adapter Operation" is executed. The parameters defined here will be stored in an implicit map called "outputParams".
To define a new "Output Parameter" use the generation tag "wr:Output" and set the "name" attribute to assign a specific name to the parameter. It's important to use meaningful names for output parameters since the name will be used to access and write the values. The name property cannot contain empty spaces and special characters.
This line of code is used to register the "Namespace".
The "Namespace" is used to provide uniquely named elements and attributes in an XML Document that contains XML nodes belonging to different vocabularies. Since each vocabulary has its own namespace, each named element and attribute can be considered unique.
Here the value must be the same as the "targetNamespace" property defined inside the WSDL Definition. In our example, the corresponding value can be found at line 2 of the WSDL Definition.
XML Document Creation
def result = document.selectSingleNode(".//GetQuoteResult")
def content = result.getText()
Document quote = DocumentHelper.parseText(content)
This line of code is used to create a "Document" object starting from the XML Document of the Web Service response.
The object is created by parsing the content of the response, using the "DocumentHelper" static class. The object is used later on to check the nodes and get the values returned by the Web Server.
Element quoteElement = quote.selectSingleNode("StockQuotes/Stock")
outputParams.symbol = quoteElement.selectSingleNode("Symbol").getText()
Once you have the "Document" object, nodes are retrieved by querying this structure using the groovy methods to select nodes in combination with "XPath" queries.
"XPath" is a language used to quickly browse a XML structure. To learn more about "XPath", refer to the resource shown.
An example of how to retrieve a node can be the "quoteElement" element type which is the node called "Stock" under the "StockQuotes" node. To express this query in "XPath", since you want to reach a sublevel you have to use the names of nodes separated with a "/". Then to retrieve the node you pass the "XPath" expression as argument of the "selectSingleNode" groovy method. Finally to retrieve the value of the node you need to append to the "selectSingleNode" method the "getText()" method which looks for it and converts it into a type text value.
Fill the Output Map
outputParams.symbol = quoteElement.selectSingleNode("Symbol").getText()
outputParams.last = quoteElement.selectSingleNode("Last").getText()
outputParams.date = quoteElement.selectSingleNode("Date").getText()
Creating the output parameters is not sufficient to provide a value for the outgoing parameters.
You need to set a value for them, and the value is the one already inside the XML Document. So first of all identify the parameter for which you want to set the value, accessing it through the implicit map "outputParams". Then assign to the value of this key the value of that XML node retrieving it from the response.
Use the method "selectSingleNode" to retrieve a single value from the response, and the "getText()" method to get the value of that node.
End of Document
At the end of the algorithm it is necessary to add the tag to close the document root. So at the end of the transformation template you have to add the "" tag.
How to Add a Template File
To ensure that you have the complete folder structure, move to the WebRatio Explorer View and expand the node related to your project. If you don’t have the "WebContent/WEB-INF" folder structure, right click on the project folder and choose "WebRatio" and then "Add WebContent folder…" command. A dialog asks you to confirm. Leave all the default options as they are, as the procedure creates the entire path that you require. Press on the "OK" button to confirm. Let's add a new folder where you can regroup all the template for the "Adapter Operation". Right-click on the "descr" folder, choose "New" and then "Folder" option. Type a name for it, such as "template_adapter". Then press the "OK" button to confirm. Now expand the "descr" folder and you can place the template file inside the "template_adapter" subfolder.
How to Use the Adapter Operation
Let's see how to use the "Adapter Operation" inside the "Action Definition" model. Since we are going to change the structure of the previous implementation, remove the "XML I/O Operation" from the model. You now want to save the result into an entity.
Take the "Adapter Operation" from the "Service Components" section of the toolbar and place it in the work area. Give a meaningful name to it like, for example "Transform Response".
Select the operation and move to the Properties View. The transformation algorithm must be referenced by the operation using the "Transformation File" property. Press on the "Browse" button to locate the template that you want to use. Select the desired file and then press on "OK" to confirm your choice.
Now let's add the necessary flows and bindings. Add an "OK Flow" starting from the "Request Response" Operation to the "Adapter Operation". Double click on it to open the "Parameters Binding" dialog and remove the "Enable Default Binding" checkmark. Set the "Output XML Document" as input for the "Input XML Document" of the "Adapter". Then press the "OK" button to confirm.
Now it's time to save the transformation results in the entity. Add a "Create Operation" to the model, by taking it from the "Operations" section of the toolbar. Place it in the workarea and give a meaningful name to it. Move to its Properties View and set the entity on which you want to write the results. Press the "Select" button next to the "Entity" property to locate the "StockQuote" entity. Press the "OK" button to confirm.
Then add an "OK Flow" connecting the "Adapter" and the "Create Operation". Double click on it to open the "Parameters Binding" dialog, and remove the "Enable Default Binding" checkmark. Now set as input for all the target attributes of the entity each output parameter coming from the "Adapter". When the parameters to manually couple are many as in this case, you can use the "Guess Binding" button. It guesses the binding comparing the names of input and output parameters. When the bindings are finished, you can see an empty binding the "oid", since the tool computes it automatically. Also, you can see an empty binding for the "Stock Quote" object, which represents the whole entity. Then press the "OK" button to confirm your choice.
Finally add another "OK Flow" that starts from the "Create" and leads to the "OK Port". Bind on this flow the "primary key" for the "StockQuote". The model of the "Action Definition" is now completed.
How to Test the Web Service
Before you can "Generate and Run" the current status of the Web application to test it, you need to make the "Site View" refer to the newly created "Stock Quote" entity. Modify the "Details" view component so that its entity is "Stock Quote", by selecting it from its Properties View, and add the display attributes you wish to visualize. Finally, edit the "Parameters Binding" of the "OK Flow" from the "Get Stock Quote" action to the "Details" view component and correct the source of the binding so that it refers to the "oid". Now you can generate and run.
As soon as the browser opens, reach the page with the form to insert the "Stock Quote Symbol". Use again as value "GOOG". Press the "Submit" button to execute the Web Service. After a few seconds you should get the response, this time showing all the separated information of the "Stock Quote" as single attributes, giving a more readable and user friendly result.