The Web Service Description Language (WSDL) - JSP

WSDL is an XML format that describes a Web service for clients. Listing 12.18 shows the WSDL file for the BookService discussed in the section on SOAP.

Listing 12.18 bookservice.wsdl

One of the first things that you will notice about this XML document is the namespaces. There are six namespaces used in this document.Table shows these namespaces and what they are used for.

A WSDL document consists of five core structures:

n <types> n <message> n <portType> n <binding> n <service>

The <types> Element

The <types> element contains the definitions of any data types that are to be passed back and forth to and from the Web service. Here is the <types> element from bookservice.wsdl:

The first thing to note is that the types are defined using the W3C XML Schema language. The type defined here is called a Book.There is a nillable element called Book, which is of the Book type. The <types> element can also import and include schemas from external sources if necessary. This is especially useful when the types are already defined elsewhere in existing schemas.

The <message> Element

What the <types> element does not define is how the types are used. It simply states what they are.The types are used in the context of parameters and return types to the Web service.The parameters and return types are defined within the WSDL file as <message> elements. Here are the message elements for bookservice.wsdl:

<wsdl:message name=”getBookByIDResponse”><wsdl:part name=”return” type=”tns1:Book”/></wsdl:message> <wsdl:message name=”getBookByIDRequest”><wsdl:part name=”in0” type=”xsd:int”/></wsdl:message>

There are two messages defined the bookserviceWeb service. One is for the request, and the other is for the response.The request parameter is an int, and the response is a Book.The Book was defined in the <types> element previously discussed.

The <portType> Element

The <portType> element is analogous to a Java class. It defines the various methods that are available to client applications. Here is the <portType> element from the bookservice.wsdl:

<wsdl:portType name=”BookRetriever”><wsdl:operation name=”getBookByID” parameterOrder=”in0”> <wsdl:input message=”intf:getBookByIDRequest”/><wsdl:output message=”intf:getBookByIDResponse”/> </wsdl:operation></wsdl:portType>

As you can see, this is almost a class definition, with the <operation> element defining the available methods, and then for each <operation>, appropriate <input> and <output> messages.The message types here correspond to the <message> elements discussed earlier.

The <operation> Element

In WSDL, it is possible to have four distinct types of operation:

  • One-way—The service receives a message, but does not respond.
  • Request-Response—The service receives a message, and then sends a reply (as in our example—this is the most common for remote procedure calls).
  • Solicit-Response—The service sends a message, and receives a reply message, the opposite of Request-Response.
  • Notification—The service sends a message. It does not receive messages.

These different operation types have different sequences of <input> and <output> elements.

The <binding> Element

The <binding> element contains the protocol-specific content for the Web service. If you look again at Table showing the namespaces used in WSDL, you will note that there are three namespaces that are associated Web service bindings.

The <binding> element is required because what has been seen up until now does not say anything about how the messages should be sent. Although the messages themselves have been defined, there is nothing specific to SOAP, for example, or any other possible protocol. At least one <binding> element is required. If your service is made available via the SOAP protocol, as the bookservice is for example, then elements from the SOAP binding namespace are used to define how the various portTypes are to be accessed. Here is the <binding> element from the bookservice.wsdl file:

This <wsdl:binding> contains a child <soap:binding> element.The SOAP binding element is from the SOAP binding namespace. The style attribute defines whether the SOAP message will be for RPC or messaging. The alternative value for the style attribute is document.The transport specified is SOAP over HTTP. It could also have been SOAP over FTP or SOAP over SMTP, which would have been specified as follows:

Within the <soap:binding> element,there is a set of elements defining the various operations along with their corresponding <input> and <output> elements.This section closely resembles the <portType> element.The purpose of these elements is to specify how the various messages are to appear in the SOAP body. In our example, this is relatively straightforward:

<wsdl:output><wsdlsoap:body use=”encoded” encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”http://localhost:8080/axis/services/bookservice”/></wsdl:output>

Here, the output from the operation (which, if you recall, returns a book object) is encoded using the standard SOAP encoding.

The <service> Element

The last element in the WSDL file is the <service> element.This element defines the actual URL of the Web service being accessed:

<wsdl:service name=”BookRetrieverService”><wsdl:port name=”bookservice” binding=”intf:bookserviceSoapBinding”> <wsdlsoap:address location=”http://localhost:8080/axis/services/bookservice”/></wsdl:port></wsdl:service>

The bookServiceSoapBinding is the name given to the binding element discussed previously.

Generating WSDL

If you are using Apache Axis, you will be pleased to know that the WSDL file can be created dynamically for you. In fact, if you successfully deployed the Web services that have been discussed so far, namely averager and bookservice, you will be able to view the WSDL file by simply visiting the following URLs in a browser:

http://localhost:8080/axis/services/averager?wsdl
http://localhost:8080/axis/services/bookservice?wsdl

In fact, these are the URLs that you would have used when accessing the services through XML Spy. It is these dynamically generated WSDL files that XML Spy uses to give you the dialog box that you can see in Figure. You can also create the WSDL file from the command line by using the Java2WSDL command-line tool that comes with Axis.

Generating Java from the WSDL

It is also possible to create the Java code from the WSDL! The tool is called WSDL2Java. This can be especially useful when developing Web applications that access Web services. If you consider the example Web application that accesses the bookservice, it consisted of a servlet (Listing 12.16), and a JSP (Listing 12.15).Within the Web application code, all the code to interact with the Web service also had to be written. WSDL2Java can be used to not only create Web services themselves, but it can be used to create client stubs to simplify the code you would need to write to access the Web service. Figure demonstrates this.

Accessing Web services using stubs.

Accessing Web services using stubs.

The benefit of using a stub is that the client application no longer needs to concern itself with interacting with the Web service directly. It can simply interact with the dynamically generated stub.

To create the stub and associated classes for the bookservice, you will need to bringup a command prompt in the folder containing the WSDL file (it has been saved for you in servicesbookservice.wsdl).Then, set the classpath to include the Axis classes,and enter the following at the prompt:java org.apache.axis.wsdl.WSDL2Java -v bookservice.wsdl

The -v flag means verbose, so you get feedback on what is going on when you run the program.The WSDL file is then passed in as an argument. Running this creates a number of classes, interfaces, and also a deployment and undeployment descriptor for the Web service. In this section, the focus will be on the generated classes that will help in the building of a Web application that accesses Web services. There are several classes that require our attention because they could be used within a Web application.The most important of the generated classes is the stub (Listing 12.19). It has been placed in a package called localhost in our example because that is the domain being used in the WSDL file.

Listing 12.19 BookserviceSoapBindingStub.java

Not all of the code from the class has been shown because it is fairly large, but the core method has been left in.The method shown is the method that accesses the Web service, and our Web client can use the class. Note the Book type referred to is from a different package (bookns).That is because a Book class has also been created by the WSDL2Java utility. It is very similar to the Book.java from Listing 12.9.

The class also implements an interface called localhost.BookRetriever.This interface contains the remote methods. It is shown in Listing 12.20.

Listing 12.20 localhost.BookRetriever.java

Notice the use of the java.rmi.RemoteException class.This has been used as the type of exception that is thrown if there is a problem invoking the remote procedure. To locate the service, an additional class is also created.This is called the BookRetrieverServiceLocator.The listing for this is not shown, but it is part of the demonstration application mentioned in the next paragraph. Finally, here is a Web application that takes advantage of these automatically generated classes.The servlet can be seen in Listing 12.21.It can be found in the clientWithStub.war web application in the chapter12.zip file.

Listing 12.21 BookClientServlet.java

The Web application within which the servlet resides is exactly the same as the one used for the earlier bookservice example.The only difference is that the JSP useBean element for the Book is now of type bookns.Book as opposed to com.conygre. webservices.Book.The compiled classes generated by WSDL2Java also need to be in the classes folder of the Web application. The main thing to notice about the servlet code in Listing 12.21 is that it has no Axis- or Web service–specific code in it any longer. It has all been hidden within the stub class, which was generated automatically.The benefits are substantial. Client developers no longer need to concern themselves with the details of SOAP or WSDL.They do not need to consider serialization issues at all because it is all taken care of.You can even generate stubs for services that are not written using the Java programming language. Web services hosted on the .NET platform, for example, can also be accessed via stubs created in this way. All that is required is a WSDL file. Finally, it is worth pointing out that there is also a Java class called Java2WSDL.This class can be used to generate WSDL bindings for your application based upon a WSDL file created from nothing more than a Java interface. It creates the class for the web service with the required methods as defined by the Java interface.You can then provide the appropriate implementation code within these methods. See the Axis documentation for more details on Java2WSDL.

Accessing WSDL Programmatically

As you would expect, it is also possible to access WSDL, programmatically.There is an API called WSDL4J that you can use, and there is also an API called the Web Service Invocation Framework, or WSIF. At the time of writing, the WSDL4J API is in the Community Review stage of the Java Community Process. It is JSR 110.WSIF is an API from the IBM AlphaWorks. It enables you to interact with Web services using SOAP based on the contents of the WSDL file.This API relies on the precursor to Apache Axis, however, which is Apache SOAP 2.2, so if you wanted to test it, you will need to download and install Apache SOAP, and place the relevant classes for Apache SOAP into the classpath.These are not compliant with Apache Axis.


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

JSP Topics