Building More Robust Web Services

The service you have created so far is fairly simplistic. When you come to create real Web Services, you will need to consider additional issues such as lifecycle and scalability. You will also approach certain tasks in a different way.

Starting from WSDL

When a system is designed, the designers will create UML diagrams (or the like) to represent the system entities and interactions between them. Tools can then generate programming artifacts, such as Java classes and interfaces based on this information. If the system will be based on Web Services, such artifacts will include WSDL descriptions of the required services. You, as a Java developer, will then be presented with a WSDL description that requires a Java implementation. The creation of WSDL independently from code is generally a better approach than starting from code and generating WSDL for reasons discussed in the sidebar “Always Start from the WSDL.”

Always Start from the WSDL

One of the reasons for the popularity of WSDL and SOAP as mechanisms for defining and implementing Web Services is that they are relatively simple. A benefit of this simplicity is that they provide a low barrier to entry for any platform or programming language that wants to join the Web Service party. However, despite their simplicity, WSDL and SOAP documents are not very friendly for humans. The sheer volume of information contained in a nontrivial interface definition and the amount of prior protocol knowledge required to fully grasp the meaning of some of the elements and attributes mean that you would not want to use WSDL documents or SOAP packets as bedtime reading.

It is good practice in any partitioned application to clearly define the interfaces between components. This is especially true of distributed applications. For this reason, most distribution mechanisms encourage developers to start by defining their distributed interface. In the case of RMI, this interface is defined in Java, whereas in other environments, such as CORBA and DCOM, the interface is defined in a language-neutral Interface Definition Language (IDL). This makes sense as RMI is mostly concerned with Java-to-Java communication, whereas CORBA and DCOM are both independent of any particular programming language. The use of IDL enables cross-language interoperation, which can be somewhat trickier if you start with RMI.

WSDL is largely another form of IDL. It allows you to define your interfaces, their protocol bindings, and the location at which the service is deployed. However, WSDL documents, like IDL documents, are somewhat inaccessible for the average developer. There is a lot of detail to learn, and it is tricky to edit raw WSDL. Because of this, most Web Service toolkits and products (including Apache Axis, Microsoft Visual Studio .NET, and the J2EE RI) provide the capability of generating a WSDL document from a language artifact, such as a Java interface definition or an ASP.NET ASMX page. The principle here is that you can just write things in the language with which you are familiar and have them exposed as a Web Service. You do not have to write any WSDL to allow a Web Service client to consume your Web Service implementation. This has many similarities to the way that a CORBA client can consume an RMI interface using a CORBA IDL interface generated with the –idl option to rmic.

Although interface generation makes an otherwise potentially awkward task a lot easier, there is a fundamental flaw in this approach, which is this:

WSDL, like IDL, was never intended to represent rich object-oriented interfaces.

The implication of this will become clear later, as you define a rich remote interface with parameters and return values consisting of encapsulated objects and collections of objects. When such an interface is translated into WSDL, the result is a far simpler description containing structures and arrays. This means that a lot of information about the behavior that you have associated with your data is lost at the Web Service interface.

When you have a rich environment at each end of the conversation, rich artifacts, such as instances of developer-defined classes, can be passed with little, if any, effort. However, if you do not know what environment is at the far end, you lose the ability to do this. If your Web Service client is a Perl application, how would it deal with your complex objects? Hence, WSDL and SOAP must cater to the lowest-common-denominator in order to provide a low barrier of entry for platforms and languages.

When a WSDL generation tool attempts to convert a developer-defined Java class into WSDL, it must cut some corners to make it fit in the data-centric typing system used by WSDL. This means that data becomes “raw”—effectively just data structures and arrays of data structures. The structure and relationships of such a description in many ways reflects quirks of the language from which it was generated. This can make it quite unwieldy when imported into a different language. The alternative is to define a pair of custom serializers and deserializers that will map your language artifact into a richer on-the-wire representation. However, this means that the sender or receiver at the other end must also know about your format and have a matching serializer/deserializer pair for their platform. Neither of these scenarios is particularly helpful.

In summary, the best approach is to start by defining the interface—in this case in WSDL. You can then use the Web Service toolkits to generate language artifacts from the WSDL. This will always provide a fairly “clean” structure as you are going from a simpler type system (data only) into a more complex one (data + behavior). If you then choose to provide custom serialization to turn the simple types into complex types, you are quite at liberty to do so. However, it is very much your own decision and does not force an unwieldy description on the other end of the conversation. It is well worth investigating tools that simplify the creation of WSDL documents—for example xmlspy—(see http://www.xmlspy.com) as these will take away the pain associated with writing WSDL by hand.


Rather than having to work out manually what sort of Java class would match that WSDL description, the J2EE RI (in common with other J2EE implementations) provides a tool to perform the mapping of the SOAP operations and XML Schema types in the WSDL document into Java artifacts. The wscompile tool can produce server-side skeletons from the WSDL document in the same way that it creates client-side stubs. One of these server-side artifacts will be a Java Remote interface that reflects the definitions from the WSDL file. You can then implement this interface (as you did previously) and package your service for deployment. The implementation still implements the Remote interface; the only difference is that this is the generated one. The build sequence is also slightly different in that you will need to run wscompile before building your Web Service implementation class rather than afterward as you did before. The rest of the configuration files would be almost identical to those for the basic greeting service.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.205.205