By Shivanand Kini, October 24, 2006
Web Services Description Language (WSDL) plays an important role in web-service development and in describing a service in a platform- and language-independent way. Service Oriented Architecture (SOA) makes use of WSDL primarily for defining strong public contracts between each service.
This article discusses the various elements of WSDL and then guides you through using the WSDL Editor, which is one of the key editors in NetBeans Enterprise Pack 5.5. It also demonstrates how to describe a simple Hello Service by using WSDL. This article then shows how to add another operation to the WSDL.
Web Services Description Language (WSDL) describes a web service in XML format. WSDL represents a contract between the service provider and the user of the service.
To make use of a web service, you must do the following:
WSDL describes a service using various constructs, or WSDL elements. The constructs can be broadly classified as abstract or concrete.
Abstract WSDL describes the operations and messages in detail. In other words, abstract WSDL specifies the what of the service:
If you are familiar with Java, you can think of abstract WSDL as an interface definition or an abstract class definition with method definitions, but no implementations.
Abstract WSDL contains two main components:
Concrete WSDL describes the how, which, and where of the service:
In the Java world, you can think of concrete WSDL like an implementation of the abstract WSDL. But in terms of web services, it just describes where the implementation can be found and used.
Concrete WSDL contains two main components:
Let's go deeper into the WSDL elements, one by one.
<wsdl:definitions>
You can specify the target namespace, name, and other prefixes that are used in the WSDL document.
The target namespace defines the namespace of the WSDL document. This is the namespace that other components (such as BPEL or other WSDLs) will use to refer to the elements within this WSDL document.
An example of a prefix definition is xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/". This prefix specifies that all elements within the schema document with the targetNamespace http://schemas.xmlsoap.org/wsdl/ will be prefixed by wsdl.
Some of the namespaces are well-known namespaces, such as schema, wsdl, and soap. Most parsers automatically recognize those documents. All other documents need to be imported into the WSDL document if you want to use it.
<wsdl:types>
This is where all the types are defined. XML Schema Language is used to define the type or element definitions.
You can create an inline schema (a schema that is defined in the Types section of a WSDL document) or you can import an external schema. The schema defines the data types used in the operations. You can view this as Java class definitions with variables that can be either primitive types or references to other class objects. The primitive types are defined in the Schema namespaces and are generally referred to as built-in types. These include simple types such as string, int, double, and so on.
You can use the primitive types to create complex types. For example, a Person type could have a String firstName, a String lastName, and so on. You can create elements out of the simple types or complex types.
WSDL allows you to use other type definition languages, such as RELAX NG.
<wsdl:import>
This WSDL element allows you to import an external WSDL, in case you want to use elements that are already defined in the external WSDL. For example, you can import an abstract WSDL, and try to implement it in the current WSDL.
<wsdl:message>
A message is a collection of one or more parts. Each part can be an element or type defined in the schema.
<wsdl:porttype>
A port type is a collection of one or more operations. An operation is like a method defined in a Java class. The four types of operations are:
<wsdl:binding>
The binding element provides specific details about how a port type's operations will be transmitted over the wire. Bindings are concrete definitions of port types. A port type can have multiple bindings. For example, one binding can define the port type in terms of the http-soap protocol, and another binding can define the port type in terms of the smtp protocol.
<wsdl:service>
A service is a collection of ports. A port defines the address where the service defined by a binding is located.
All of the elements allow for a <wsdl:documentation> element, which provides a way to include human-readable documentation about the element.
WSDL allows you to define extensibility elements in various sections of WSDL elements, including the binding, service, and definitions.
We are now going to create a simple project based on a sample application. We will use this project to learn about the different features of the WSDL editor.
Follow these steps to create the sample project:
In the IDE, from the main menu, choose File > New Project.
In the Categories list, expand the Samples node and select the Service Oriented Architecture node.
In the Projects list, select the Synchronous BPEL Process node.
Click Next.
(Optional) Change the Project Location field.
Click Finish.
The SynchronousSample project is created.
Expand the Process Files node and double-click the SynchronousSample.wsdl file node.
The tab that opens for the .wsdl file in the Source Editor is the WSDL Editor.
The WSDL Editor shows a tree of all the elements in the WSDL document, categorized under different sections for Types, Messages, Port Types, and so on. This view is called the WSDL view. There is also a Source view, which shows the source code that is generated.
The toolbar contains the Source and WSDL buttons which let you switch between the Source view and the WSDL view of the .wsdl file. The tree and column buttons let you switch between a tree and column view of the document elements within the WSDL view. Finally, the Validate button lets you validate the WSDL document.
There are two differences between the Tree view and Column view: the layout of the nodes and the fact that the Column view does not have a root node.
Other than these two differences, all actions and property sheets are the same regardless of which view is used. You can choose whichever view you are comfortable with. We will use the Tree view in this document for further exploration.
Both views have seven sections or categories:
If the Properties window is not open, choose Window > Properties from the main menu, or press Ctrl-Shift-7.
When you click the nodes in the tree, the information in the Properties window changes to show the attributes for the selected node.
You can change the property values by using the inline editor for the property or opening the custom editor by clicking the ellipsis button (...).
When you right-click a node, a pop-up menu opens. The options that are enabled on the menu depend on the selected node.
There are two ways to create a WSDL document in the IDE:
Process Files node > New > WSDL Document > New WSDL Document wizard. Process Files node > New > File/Folder > XML node and External WSDL Document node > New Retrieve Documents wizard. The IDE help topic titled "Creating a WSDL File" provides detailed steps for both ways.
Assume that we want to create a service that takes the user's name and returns "Hello <name>".
Which operations are needed?
Probably in Java, you would do something like this:
String sayHello(String name) {
return "Hello " + name;
}
In order to describe this in WSDL:
We have an operation called sayHello.
The input message is a message with one part called name and its type is xsd:string.
The output message is a message with one part called name and its type is xsd:string.
What type of protocol can be used to call this operation?
We can use different protocols like soap over different transports like http, ftp, or smtp. In this example, let's use soap over http.
In case of soap, there are different formats available:
document-literal This mandates that the elements be used in WSDL parts. rpc-literal This mandates that types be used in WSDL parts. rpc-encoded
The most commonly used format is document-literal. Let's use this format in our example.
Where will the service run?
Once a protocol is selected, we need to find the address where the service will be available for use.
Since we are using soap-http, let's say the address is http://localhost:12121/helloService. The port number in the example is a random number; if this doesn't work, use a port that is available.
Now we have all the answers to describe the service. The first question describes the abstract part of the WSDL. The second and third questions describe the concrete part of the WSDL.
Let's see how we can do this by using the WSDL Editor in the IDE.
Let's create a new BPEL Module project, considering that we want to implement our service using BPEL.
From the IDE main menu, choose File > New Project.
In the Categories list, select the Service Oriented Architecture node and in the Projects list, select BPEL Module.
Click Next.
In the Name and Location page, change the Project Name field to helloProj
Click Finish.
Right-click the Process Files nodes under the helloProj node and choose New > File/Folder.
In the Categories list, select the XML node, and in the File Types list, select XML Schema.
Click Next.
In the Name and Location page, change the Project Name field to hello and notice that the Target Namespace field changes to http://xml.netbeans.org/schema/hello.
Click Finish.
The IDE adds the new schema file and opens the Schema view of the XML schema editor for your new hello.xsd file.
In the Schema view, click the column button to make sure you are in the column mode of the view.
In the first column of the Schema view, select the Elements node, right-click and choose Add Element from the pop-up menu.
The Element dialog box opens.
Do the following to define the new element:
In the Name field, type stringElement.
Under Type, select the Use Existing Type radio button and in the list of types, expand the Built-in Types node and select string
Click OK.
Save your work by choosing File > Save All from the IDE main menu.
Now let's see how we can create a WSDL using the information we gathered above.
Under the helloProj project node in the Projects window, right-click the Process Files node and choose New > WSDL Document from the pop-up menu.
The New WSDL Document wizard opens.
Change the File Name field to hello and click Next.
The Abstract Configuration page opens.
In the Abstract Configuration page, do the following:
Do not change the Port Type Name.
Change the Operation Name to sayHello.
From the Operation Type drop-down list, select Request-Response Operation.
Under Input, in the Message Part Name column, change part1 to request and press Enter.
Under Input, in the Element Or Type column, click the ellipsis button.
The Select Element Or Type dialog box opens.Under the helloProj node, expand the src/hello.xsd node, and select stringElement under the Elements node.
Click OK.
Under Output, change part1 to response and select stringElement as the type using the same steps as above.
Click Next.
The Concrete Configuration page opens.
Since we selected the element in the parts, we must select Document Literal as the Binding Subtype.
Click Finish.
The IDE opens the WSDL view of the WSDL editor for your new file, hello.wsdl.
In the WSDL view, expand Services > helloService > helloPort and select the soap:address node.
In the Properties window, change the Location property to http://localhost:12121/helloService; we wanted our service to be at this location.
Save your changes by choosing File > Save All from the IDE main menu.
In the WSDL view of the WSDL editor, click the Validate button.
Make sure that the Output window matches the following:
XML validation started.
0 Error(s), 0 Warning(s).
XML validation finished
This completes the WSDL for the initial requirement.
Let's assume that we want to have another operation called sayHelloWithRespect. The service takes in the name, last name, and salutation that the user wants and returns Hello <Salutation> <lastName>.
String sayHelloWithRespect(String firstName, String lastName, String salutation) {
return "Hello " + salutation + lastName;
}
Let's modify the current WSDL to add this operation.
If hello.wsdl is not open in the WSDL editor, open it now.
Right-click the Types node and choose Add > Inline Schema from the pop-up menu.
The IDE adds a new subnode under the Types node and the new node is labeled (No Target Namespace).
Select the new node, and in the Properties window, change the Target Namespace property to http://xml.netbeans.org/helloWithRespect.
Add a new element called personDetails by doing the following:
Select the http://xml.netbeans.org/helloWithRespect node, right-click and choose Add > Element from the pop-up menu.
The Element dialog box opens.
In the Name field, type personDetails, under Type, select the Inline Complex Type radio button and click OK.
Under the http://xml.netbeans.org/helloWithRespect node, expand the Elements node and select the personDetails node.
Create three elements under the personDetails sequence called firstName, lastName, and salutation. Make sure each element is a string.
In the WSDL editor, under the hello root node, select the Messages node, right-click and choose Add Message from the pop-up menu.
Rename the new message1 to personDetailsRequest using the Properties window.
Change the part1 part under personDetailsRequest as follows:
Use the Properties window to rename the part to personDetails.
Click the ellipsis button in the Element or Type property to select the personDetails element from the inline schema.
Add a new operation to the helloPortType port type by doing the following:
In the WSDL editor, under the hello root node, expand the Port Types node, select the helloPortType node, right-click and choose Add > Operation from the pop-up menu.
The Create New Operation dialog box opens.
Change the Operation Name field to sayHelloWithRespect.
From the Operation Type drop-down list, select Request-Response operation.
From the Input drop-down list, select the tns:personDetailsRequest message.
From the Output drop-down list, select tns:sayHelloReply.
Click OK.
The new operation appears in the WSDL editor.
Add a new binding operation by doing the following:
In the WSDL editor, under the hello root node, expand the Bindings node, select the helloBinding node, right-click and choose Add > Binding Operation from the pop-up menu.
The IDE adds the newly created operation and its content to the binding.
Right-click the sayHelloWithRespect binding operation node and choose Add SOAP Operation from the pop-up menu.
Right-click the input2 node and choose Add SOAP Body from the pop-up menu.
With the new soap:body node selected, change the use property in the Properties window to literal.
Right-click the output2 node and choose Add SOAP Body from the pop-up menu.
With the new soap:body node selected, change the use property in the Properties window to literal.
Save the WSDL file.
Messages node, right-click the sayHelloRequest message node and choose Find Usages from the pop-up menu. This tells you that there is one usage of the message and it is used in the input1 of the sayHello operation in the helloPortType port type.
Let's say you wanted to change the name of the operation sayHelloWithRespect to sayHelloWithSalutation and you wanted to make sure that all the references to sayHelloWithRespect were updated with the new name. To do this, you would use the refactoring function in the IDE.
Under the Port Types node, expand the helloPortType node.
Select the sayHelloWithRespect node, right-click and choose Refactor > Rename from the pop-up menu.
The Rename dialog box opens.
Change the New Name field to sayHelloWithSalutation, make sure that the Preview All Changes checkbox is selected and click Next.
All the references to this operation are shown in the XML Refactoring window.
You can see that the binding operation has a reference. You can select or clear each change.
Click Do Refactoring.
All the references and the node that is renamed will be renamed.
NetBeans Enterprise Pack 5.5 enables you to quickly create and edit WSDL files.