Monday, September 5, 2011

JWS

WS

  • SOAP

  • REST



Simple Object Access Protocol (Service Oriented Architecture)
Representational State Transfer


A SOAP-based web service could be implemented as a single Java class but, following best practices, there should be an interface that declares the methods, which are the web service operations, and an implementation, which defines the methods declared in the interface. The interface is called the SEI: Service Endpoint Interface. The implementation is called the SIB: Service Implementation Bean


The other WSDL section of interest is the last, the service section, and in particular the service location, in this case the URL http://localhost:9876/ts. The URL is called the service endpoint and it informs clients about where the service can be accessed.


message exchange pattern (MEP)—request/response

WSDL - web service definition language

A SOAP-based web service should provide, as a WSDL document, a service contract for its potential clients. So far we have seen how a Perl, a Ruby, and a Java client can request the WSDL at runtime for use in the underlying SOAP libraries. Chapter 2 studies the WSDL more closely and illustrates how it may be used to generate client-side artifacts such as Java classes, which in turn ease the coding of web service clients. The Java clients in Chapter 2 will not be written from scratch, as is our first Java client. Instead such clients will be written with the considerable aid of the wsimport utility, as was the TeamClient shown earlier. Chapter 2 also introduces JAX-B (Java API for XML-Binding), a collection of Java packages that coordinate Java data types and XML data types. The wsgen utility generates JAX-B artifacts that play a key role in this coordination; hence, wsgen also will get a closer look.

XML-qualified name (a Java QName), which in turn consists of the service's local name (in this case, TimeServerImplService) and a namespace identifier (in this case, the URI http://ts.ch01/)

Building a client for the web service
wsimport -keep -p client http://localhost:9876/ts?wsdl
wsimport -keep -p client ts.wsdl

@WebMethod
@WebResult(partName = "time_response")
String getTimeAsString();


2.2 WSDL Structure
At a high level, a WSDL document is a contract between a service and its consumers. The contract provides such critical information as the service endpoint, the service operations, and the data types required for these operations. The service contract also indicates, in describing the messages exchanged in the service, the underlying service pattern, for instance, request/response or solicit/response. The outermost element (called the document or root element) in a WSDL is named definitions because the WSDL provides definitions grouped into the following sections:

The types section, which is optional, provides data type definitions under some data type system such as XML Schema. A particular document that defines data types is an XSD (XML Schema Definition). The types section holds, points to, or imports an XSD. If the types section is empty, as in the case of the TimeServer service, then the service uses only simple data types such as xsd:string and xsd:long.

Although the WSDL 2.0 specification allows for alternatives to XML Schema (see http://www.w3.org/TR/wsdl20-altschemalangs), XML Schema is the default and the dominant type system used in WSDLs. Accordingly, the following examples assume XML Schema unless otherwise noted.

The message section defines the messages that implement the service. Messages are constructed from data types either defined in the immediately preceding section or, if the types section is empty, available as defaults. Further, the order of the messages indicates the service pattern. Recall that, for messages, the directional properties in and out are from the service's perspective: an in message is to the service, whereas an out message is from the service. Accordingly, the message order in/out indicates the request/response pattern, whereas the message order out/in indicates the solicit/response pattern. For the TimeServer service, there are four messages: a request and a response for the two operations, getTimeAsString and getTimeAsElapsed. The in/out order in each pair indicates a request/response pattern for the web service operations.

The portType section presents the service as named operations, with each operation as one or more messages. Note that the operations are named after methods annotated as @WebMethods, a point to be discussed in detail shortly. A web service's portType is akin to a Java interface in presenting the service abstractly, that is, with no implementation details.

The binding section is where the WSDL definitions go from the abstract to the concrete. A WSDL binding is akin to a Java implementation of an interface (that is, a WSDL portType). Like a Java implementation class, a WSDL binding provides important concrete details about the service. The binding section is the most complicated one because it must specify these implementation details of a service defined abstractly in the portType section:

The transport protocol to be used in sending and receiving the underlying SOAP messages. Either HTTP or SMTP (Simple Mail Transport Protocol) may be used for what is called the application-layer protocol; that is, the protocol for transporting the SOAP messages that implement the service. HTTP is by far the more popular choice. The WSDL for the TimeServer service contains this segment:

transport="http://schemas.xmlsoap.org/soap/http">

The value of the transport attribute signals that the service's SOAP messages will be sent and received over HTTP, which is captured in the slogan SOAP over HTTP.

The style of the service, shown earlier as the value of the style attribute, takes either rpc or document as a value. The document style is the default, which explains why the SEI for the TimeServer service contains the annotation:

@SOAPBinding(style = Style.RPC)

This annotation forces the style attribute to have the value rpc in the Java-generated WSDL. The difference between the rpc and the document style will be clarified shortly.

The data format to be used in the SOAP messages. There are two choices, literal and encoded. These choices also will be clarified shortly.

The service section specifies one or more endpoints at which the service's functionality, the sum of its operations, is available. In technical terms, the service section lists one or more port elements, where a port consists of a portType (interface) together with a corresponding binding (implementation). The term port derives from distributed systems. An application hosted at a particular network address (for instance, 127.0.0.1) is available to clients, local or remote, through a specified port. For example, the TimeServer application is available to clients at port 9876.


By default, a Java SOAP-based web service is wrapped doc/lit, that is, wrapped document style with literal encoding.

The @XmlType and @XmlRootElement annotations direct the marshaling of Skier objects, where marshaling is the process of encoding an in-memory object (for example, a Skier) as an XML document so that, for instance, the encoding can be sent across a network to be unmarshaled or decoded at the other end. In common usage, the distinction between marshal and unmarshal is very close and perhaps identical to the serialize/deserialize distinction. I use the distinctions interchangeably. JAX-B supports the marshaling of in-memory Java objects to XML documents and the unmarshaling of XML documents to in-memory Java objects.

The annotation @XmlType, applied in this example to the Person class, indicates that JAX-B should generate an XML Schema type from the Java type. The annotation @XmlRootElement, applied in this example to the Skier class, indicates that JAX-B should generate an XML document (outermost or root) element from the Java class. Accordingly, the resulting XML in this example is a document whose outermost element represents a skier; and the document has a nested element that represents a person.

JAX-B JAVA To XML Binding

@XmlRootElement(name = "getTimeAsElapsedResponse", namespace = "http://ts.ch02/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getTimeAsElapsedResponse", namespace = "http://ts.ch02/")
public class GetTimeAsElapsedResponse {
@XmlElement(name = "return", namespace = "")
private long _return;
public long get_return() { return this._return; }

public void set_return(long _return) { this._return = _return; }
}


@XmlRootElement(name = "NordicSkier")

How the wsgen utility and the JAX-B packages interact in JWS now can be summarized. A Java web service in document rather than rpc style has a nonempty types section in its WSDL. This section defines, in the XML Schema language, the types required for the web service. The wsgen utility generates, from the SIB, Java classes that are counterparts of XSD types. These wsgen artifacts are available for the underlying JWS libraries, in particular for the JAX-B family of packages, to convert (marshal) instances of Java types (that is, Java in-memory objects) into XML instances of XML types (that is, into XML document instances that satisfy an XML Schema document). The inverse operation is used to convert (unmarshal) an XML document instance to an in-memory object, an object of a Java type or a comparable type in some other language. The wsgen utility thus produces the artifacts that support interoperability for a Java-based web service. The JAX-B libraries provide the under-the-hood support to convert between Java and XSD types. For the most part, the wsgen utility can be used without our bothering to inspect the artifacts that it produces. For the most part, JAX-B remains unseen infrastructure.

SOAP Message

Optional SOAP Header \_ SOAP Envelope
Required SOAP Body /

Optional SOAP attachments


SOAP handlers


Recall that a SOAP envelope has a required body, which may be empty, and an optional header. An intermediary should inspect and process only the elements in the SOAP header rather than anything in the SOAP body, which carries whatever cargo the sender intends for the ultimate receiver alone. The header, by contrast, is meant to carry whatever meta-information is appropriate for either the ultimate receiver or intermediaries.

JWS provides a handler framework that allows application code to inspect and manipulate outgoing and incoming SOAP messages. A handler can be injected into the framework in two steps:


  1. One step is to create a handler class, which implements the Handler interface in the javax.xml.ws.handler package. JWS provides two Handler subinterfaces, LogicalHandler and SOAPHandler. As the names suggest, the LogicalHandler is protocol-neutral but the SOAPHandler is SOAP-specific. A LogicalHandler has access only to the message payload in the SOAP body, whereas a SOAPHandler has access to the entire SOAP message, including any optional headers and attachments. The class that implements either the LogicalHandler or the SOAPHandler interface needs to define three methods for either interface type, including handleMessage, which gives the programmer access to the underlying message. The other two shared methods are handleFault and close. The SOAPHandler interface requires the implementation to define a fourth method, getHeaders.


  2. The other step is to place a handler within a handler chain. This is typically done through a configuration file, although handlers also can be managed through code.


JWS has two different ways to throw SOAP faults and the example illustrates both. The simplest way is to extend the Exception class (for example, with a class named FibException) and to throw the exception in a @WebMethod whenever appropriate. JWS then automatically maps the Java exception to a SOAP fault. The other way, which takes more work, is to throw a fault from a handler. In this case, a SOAPFaultException is created and then thrown.

The top-to-bottom sequence of the handlers in the configuration file determines the order in which handler methods of one type (e.g., SOAPHandler) execute. The runtime ordering may differ from the order given in the configuration file. Here is the reason:


  • For an outbound message (for instance, a client request under the request/response MEP), the handleMessage method or handleFault method in a LogicalHandler code execute before their counterparts in a SOAPHandler.



  • For an inbound message, the handleMessage method or handleFault method in a SOAPHandler code execute before their counterparts in a LogicalHandler.

No comments: