Section 12.2. Brief Introduction to Web Services


12.2. Brief Introduction to Web Services

Let's start with a brief overview of web services and the basic protocols used in web services: SOAP and WSDL. If you're already familiar with web services (perhaps from experience developing them on other platforms) and you want to dive into the details of using web services in Java, you can skip directly to the next main section, "Java Web Services."

A web service is a software component that communicates using XML-formatted messages, transmitted over a standard network protocol such as HTTP (the core protocol behind the Web) or SMTP (the core protocol used by most email servers). These XML messages are formatted using SOAP. A web service can also (optionally) export a description of the service it provides, which includes the operations that it can perform and the specific types and formats of the messages it expects. These service descriptors are typically in WSDL. The WSDL descriptor for a web service describes the types of data, messages, and operations that a web service supports and where the service can be located on the network. A client can use this WSDL service description to automatically generate client-side interfaces to interact with web services.

Web services can also be (optionally) registered with a web service registry. Without a web service registry, a client needs to acquire the WSDL description of the service through some direct, ad hoc channel, such as picking up the WSDL from a local file or loading it from a predetermined web site. A registry based on an industry standard, such as UDDI or ebXML, allows a client to acquire the WSDL for a service using a well-defined protocol and a protocol that supports more functionality, such as searching for web services based on their capabilities. Discussion of web service registries and UDDI/ebXML is outside the scope of this chapter, but if you're interested in using or creating directories of web services, please consult Java Web Services or Java Web Services in a Nutshell by Kim Topley, both from O'Reilly.

12.2.1. Simple Object Access Protocol (SOAP)

The SOAP acronym is the butt of more than a few jokes in the industry, since SOAP is not really that simple, and there are no true objects in the specification. Still, it's easy to remember, which is at least half of the purpose of most acronyms. SOAP is an industry standard that is managed and published by the World Wide Web Consortium (W3C). The current version of the SOAP specification can always be found on the W3C web site at the URL http://www.w3.org/TR/SOAP.

It's important to keep in mind that SOAP defines only the format for the messages that web services send and receive. It doesn't define an API at all. SOAP defines only how to package a message into a standard format that can then be delivered using a standard transfer protocol like HTTP or SMTP. APIs come into the picture when you need to generate and consume SOAP messages within a particular programming environment.

So what does a SOAP message look like? Well, every SOAP message must include an envelope and a body. The envelope contains information about how the message is encoded and definitions for various XML schemas that are used in the message contents. These XML schemas provide descriptions of various XML elements that are used in the SOAP message and can be used to both construct and validate SOAP messages and XML documents in general. More details on XML schemas can be found in Chapter 7. The body of the message contains XML-encoded information. The information can represent a specific request made by a client to a web service, it can be information returned as the result of a request, or it can be details on why a web service request failed.

Figure 12-1 shows a sample SOAP message demonstrating a remote procedure call being made by a client to a web service via HTTP. This sample SOAP message is being sent over HTTP, so HTTP headers specify the HTTP request type (POST, in this case), the actual contents of the HTTP request, and the HTTP location to which the request is being sent (http://myservices.com/myapp/services/peopleFinder in this example). There is also a SOAP-specific custom header, SOAPAction, that specifies the entry point of the web service that should receive the enclosed SOAP message if the HTTP URL is not sufficient. In this example, no additional information is needed to locate the service on the server, so the SOAPAction header is blank. The body of the HTTP request contains the entirety of the SOAP message being sent to the web service. In this example, the envelope contains references to a number of XML Schema namespaces being invoked in the message and an indication that the message is using the default SOAP encoding style for the message. The header contains a single element, which is using a custom application schema to specify some kind of access control parameter for the message. Finally, the body of the SOAP message contains a request to invoke the findPeople operation on the target web service, with a single argument, an array of SearchArg XML elements.

Figure 12-1. Sample SOAP message


A SOAP web service, therefore, is a runtime entity that can accept SOAP messages such as the one shown in Figure 12-1, do what's requested in the message, and generate an appropriate response in the same general SOAP format.

Luckily, it's unlikely that you'll need to directly parse or generate the SOAP content in these messages. Instead, you'll rely on a SOAP web service engine of some kind to convert your native programming entities (objects, data structures, and the like) into SOAP and back again. The process of converting programming entities to SOAP XML is called serialization (the same term used in RMI and java.io to refer to converting a Java object to a binary, streamable format). The process of converting the SOAP XML back into programming entities is called deserialization. In the Java/J2EE environment, SOAP serialization and deserialization are handled by a Java web service engine, such as Axis or JBossWS.

12.2.2. Web Service Description Language (WSDL)

Suppose you've written a web service , and now you want to advertise your service to the world. You need some way to tell potential users about the serviceto describe things like where the service is available on the network, what operations it supports, what message formats it expects, and what message formats your clients can expect to receive in response to their requests. There are a number of ad hoc ways to do thisyou could post example messages to and from your web service to demonstrate how a client should interact with the service, you could write up the relevant details as a help document and post it on a web page somewhere, you could write sample client code for your web service in various languages and distribute it to potential users.

The problem with all of these approaches is that they're ad hoc and therefore not easily reproducible for either the web service publisher or the clients. If you write another web service, you need to create a similar set of sample messages, hand-written documentation, or client libraries, and developers of clients for the service will need to manually incorporate the new service based on this ad hoc information. And meanwhile, people offering their own web services are going to describe them in their own ad hoc way, making the whole situation pretty confusing and error-prone.

Ideally, there would be a standard format for describing web services that could be used by the publishers and consumers of web services. Publishers of web services would generate the description of each of their web services in the standard format, and consumers would take these descriptions and use them to generate calls to the services from their application environments. And since the web service descriptions are standardized, tools can be written to autogenerate descriptors for web services and to autogenerate client code from existing service descriptors.

Thankfully, smart people have already thought of this, and the result is WSDL. WSDL is an XML format that describes web services in terms of the operations that they support and the messages and data types that these operations expect as arguments and return as responses. WSDL uses a set of XML entities to describe web services. Example 12-1 shows the general contents of a WSDL descriptor.

Example 12-1. Skeleton WSDL descriptor
 <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions         targetNamespace="http://myserver.com/services/peopleFinder"         xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">     <wsdl:types>         <schema . . .>             <complexType name="type1">               . . .             </complexType>             . . .         </schema>         . . .     </wsdl:types>     <wsdl:message name="message1">         <wsdl:part name="messageRequest" type="ns:type1"/>     </wsdl:message>     . . .     <wsdl:portType name="PeopleFinder">         <wsdl:operation name="findPeople" parameterOrder="args">             <wsdl:input message="impl:messageRequest"                         name="findPeopleRequest"/>             <wsdl:output . . ./>             <wsdl:fault . . ./>         </wsdl:operation>         . . .     </wsdl:portType>     <wsdl:binding name="peopleFinderSoapBinding"                   type="impl:PeopleFinderImpl">         <wsdlsoap:binding style="rpc"                           transport="http://schemas.xmlsoap.org/soap/http"/>         <wsdl:operation name="findPeople">           . . .         </wsdl:operation>     </wsdl:binding>     . . .     <wsdl:service name="PeopleFinderImplService">         <wsdl:port binding="impl:peopleFinderSoapBinding"                    name="peopleFinder">             <wsdlsoap:address                  location="http://myserver.com:8080/services/peopleFinder"/>         </wsdl:port>    </wsdl:service>    . . . </wsdl:definitions> 

In order to make sense of the WSDL format, it helps to think of it in terms of the entities that go into a WSDL description of a web service. These entities and the bottom-up approach that WSDL uses to define services are shown in Figure 12-2.

At the beginning of the WSDL food chain are data types , which are the building blocks for SOAP messages. A data type can be as simple as a string, or it can be a complicated XML structure with internal hierarchy. Here is the WSDL data type containing data about a person, consisting of three strings (first name, last name, and ID):

     <?xml version="1.0" encoding="UTF-8"?>     <wsdl:definitions . . .>       <wsdl:types>         <schema . . .>           <complexType name="Person">             <sequence>               <element name="firstName" nillable="true"                        type="soapenc:string"/>               <element name="lastName" nillable="true"                        type="soapenc:string"/>               <element name="id" nillable="true"                        type="soapenc:string"/>             </sequence>           </complexType>         </schema>       . . .     </wsdl:definitions> 

Figure 12-2. WSDL entity model


A message is one or more data types grouped together. Messages are used as the inputs, outputs, and faults used by operations . Here is the WSDL definition of a message containing a Person data entity:

     <wsdl:definitions . . .>       . . .       <wsdl:message name="findPersonResponse">         <wsdl:part name="findPersonReturn" type="impl:Person"/>       </wsdl:message>       . . .     </wsdl:definitions> 

An operation represents the atomic unit of work for a web serviceclients invoke operations on the service to get work done. Port types are groupings of operations into sensible interfaces. The following example defines a port type that contains a single operation. The operation has input and output messages as well as fault messages that can be thrown if an error occurs:

     . . .       <wsdl:portType name="PeopleFinderImpl">         <wsdl:operation name="findPerson" parameterOrder="args">           <wsdl:input message="impl:findPersonRequest"                       name="findPersonRequest"/>           <wsdl:output message="impl:findPersonResponse"                        name="findPersonResponse"/>           <wsdl:fault message="impl:BadArgumentFault"                       name="BadArgumentFault"/>           <wsdl:fault message="impl:NoSuchPersonFault"                       name="NoSuchPersonFault"/>         </wsdl:operation>      </wsdl:portType>     . . . 

A port type represents a conceptual description of a web service entry point. But a potential client of the service entry point still needs to know how this port type has been "instantiated." In other words, how and where is this port callable? Over HTTP or SMTP or some other communication scheme? Using SOAP or some other encoding protocol? At what physical location(s) on the network? WSDL provides this information in the form of bindings and physical service descriptions. A binding describes how a particular port type has been bound to a communication and encoding protocol. The following shows the PeopleFinderImpl port type bound to SOAP over HTTP, for example:

     . . .       <wsdl:binding name="peopleFinderSoapBinding" type="impl:PeopleFinderImpl">         <wsdlsoap:binding style="rpc"               transport="http://schemas.xmlsoap.org/soap/http"/>         <wsdl:operation name="findPerson">           <wsdlsoap:operation soapAction="urn:findPerson"/>           <wsdl:input name="findPeopleRequest">             <wsdlsoap:body                 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"                 namespace="http://myservices" use="encoded"/>           </wsdl:input>           <wsdl:output name="findPeopleResponse">             <wsdlsoap:body                 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"                 namespace="http://myservices" use="encoded"/>           </wsdl:output>           <wsdl:fault name="BadArgumentFault">             <wsdlsoap:fault                 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"                 name="BadArgumentFault"                 namespace="http://myservices" use="encoded"/>           </wsdl:fault>           . . .       </wsdl:operation>     </wsdl:binding>     . . . 

Finally, the following shows a WSDL service, which ties the HTTP/SOAP binding of the port type to a physical address that can be used by clients:

     . . .       <wsdl:service name="PeopleFinderImplService">         <wsdl:port binding="impl:peopleFinderSoapBinding" name="peopleFinder">           <wsdlsoap:address               location="http://myserver.com:8080//services/peopleFinder"/>         </wsdl:port>       </wsdl:service>     . . . 

This hierarchical definition of a service provides a client with all the information it needs to determine whether it can talk to this service (i.e., does it use protocols and encodings that the client can handle?) and to actually make a connection to a physical endpoint (in this case, a URL).

12.2.3. Web Service Styles and Encoding

Before we jump into the Java implementations of these web service protocols, this is a good point to briefly discuss an often confusing aspect of web services: styles and encodings.

As we saw in the previous discussion of SOAP and WSDL, web services are made up of ports. Each port has one or more operations; each operation has input, output, and fault messages associated with it; and each of these messages is composed of XML data types. SOAP messages sent to a service and SOAP messages generated from a service need to be composed in such a way that it is clear which operation in which port is in effect and how the message types are expressed in the XML of the message. SOAP messages to and from a service can be formatted in several ways, and these formatting options boil down to picking a style and an encoding for the body of the SOAP message.

The style of the message refers to how the XML structure of the SOAP body is structured. The two options for the style are:


RPC

In this style, the XML of the SOAP body is structured to match the operation and message definitions. The root element of the body is named after the operation name in effect, for example, and there is one child element for each message (input or output, depending on whether the operation is receiving or sending the SOAP message). In the WSDL for the service, each message definition can contain multiple parts, and each part references an XML data type (one defined in the WSDL, in the standard XML Schema data types, or in an XML data type imported in the WSDL).


Document

In this style, the root element of the SOAP body is matched to the operation name, but the contents of the root element are not reflective of the signature of the operation. Instead, a single XML data type specifies the entire structure of the SOAP message body, and that structure can be in whatever form you like. In the WSDL for the service, each message definition contains a single part, and the part references the XML data type that defines the structure of the message body.

The names of these styles might lead you to assume that RPC style can be used only for bidirectional procedure calls, while document style can be used only for one-way messaging. But that's not the case. These styles do lend themselves well to these respective communication styles (hence their names), but they can actually be used in any context.

The other SOAP formatting option is the encoding of the message. The encoding determines how data is encoded into XML within the message. The two options for the encoding of service messages are:


Literal

This option specifies that the XML structure of the data within the message will be totally specified by XML Schema elements referenced in the WSDL description of the service. The XML data types in the WSDL (or imported by the WSDL) will be used literally to encode the XML data in the message.


SOAP-encoded

This option requests that the message data follow the default encoding rules (and XML structures) specified in the SOAP specification. These rules specify things like "each data member on a particular message element will be represented as a child XML element," whereas the literal encoding style lets you determine whether a particular piece of data should be an element or an attribute.

The combination of a style and an encoding option results in an overall format for a web service. The two combinations that are most commonly used are document/literal and RPC/encoded. The details on when and why these two service formats are preferred (or not) are beyond the scope of this short tutorial. We mention these details so that you are aware that there are different options in formatting the SOAP messages for your service, in case interoperability issues arise with your web services, for example. The web service examples in this chapter all have been implemented and deployed using the RPC/encoded format.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net