93
JAX-RPC vs JAX-WS Java API for XML-Based RPC (JAX-RPC) is a Legacy Web Services Java API, it uses SOAP and HTTP to do RPCs over the network and enables building of Web services and Web applications based on the SOAP 1.1 specification, Java SE 1.4 or lower, or when rpc/encoded style must be used. You can use the JAX-RPC programming model to develop SOAP-based web service clients and endpoints. JAX- RPC enables clients to invoke web services developed across heterogeneous platforms. Likewise, JAX-RPC web service endpoints can be invoked by heterogeneous clients. JAX-RPC requires SOAP and WSDL standards for this cross-platform interoperability. JAX-RPC lets people develop a web service endpoint using either a

Jax Rpc Versus Jax Ws

Embed Size (px)

DESCRIPTION

Jax Rpc Versus Jax Ws

Citation preview

Page 1: Jax Rpc Versus Jax Ws

JAX-RPC vs JAX-WS Java API for XML-Based RPC (JAX-RPC) is a Legacy Web Services Java API, it uses SOAP and HTTP to do RPCs over the network and enables building of Web services and Web applications based on the SOAP 1.1 specification, Java SE 1.4 or lower, or when rpc/encoded style must be used.

You can use the JAX-RPC programming model to develop SOAP-based web service clients and endpoints. JAX-RPC enables clients to invoke web services developed across heterogeneous platforms. Likewise, JAX-RPC web service endpoints can be invoked by heterogeneous clients. JAX-RPC requires SOAP and WSDL standards for this cross-platform interoperability.

JAX-RPC lets people develop a web service endpoint using either a Servlet or Enterprise JavaBeans (EJB) component model. The endpoint is then deployed on either the Web or EJB container, based on the corresponding component model. Endpoints are described using a Web Services Description Language (WSDL) document.(This WSDL document can be published in a public or private registry,

Page 2: Jax Rpc Versus Jax Ws

though this is not required). A client then uses this WSDL document and invokes the web service endpoint.

JAX-RPC in J2ee 1.4 supports 4 types of stubs and invocations: static stub, dynamic proxy, Dynamic Invocation Interface (DII) and Application client.

Static Stub ClientWeb service client makes a call through a stub, a local object that acts as a proxy for the remote service. Because the stub is created by wscompile at development time (as opposed to runtime), it is usually called a static stub.

Example: Invoking a Stub ClientStub stub = (Stub) (new MyHelloService_Impl().getHelloIFPort());stub._setProperty (javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,endpoint_address_string);HelloIF hello = (HelloIF)stub;System.out.println(hello.sayHello("Duke!"));

Dynamic Proxy ClientIn contrast, the client call a remote procedure through a dynamic proxy, a class

Page 3: Jax Rpc Versus Jax Ws

that is created during runtime. Although the source code for the static stub client relies on an implementation-specific class, the code for the dynamic proxy client does not have this limitation.

Example: Dynamic Proxyjavax.xml.rpc.Service service = ServiceFactory.newInstance().createService(...);com.example.StockQuoteProvider sqp = (com.example.StockQuoteProvider)service.getPort(portName, StockQuoteProvider.class);float price = sqp.getLastTradePrice("ACME");

Dynamic Invocation Interface ClientWith the dynamic invocation interface (DII), a client can call a remote procedure even if the signature of the remote procedure or the name of the service is unknown until runtime. In contrast to a static stub or dynamic proxy client, a DII client does not require runtime classes generated by wscompile.

Example: Dynamic Invocation Interfacejavax.xml.rpc.Service service = ServiceFactory.newInstance().createService(...);

Page 4: Jax Rpc Versus Jax Ws

javax.xml.rpc.Call call = service.createCall(portName, "getLastTradePrice");// This example assumes that addParameter and setReturnType methods are not required to be calledObject[] inParams = new Object[] {"ACME"};Float quotePrice = (Float)call.invoke(inParams);

Application ClientUnlike the stand-alone clients, for an application client, because it's a J2EE component, an application client can locate a local web service by invoking the JNDI lookup method.

Example: Application ClientContext ic = new InitialContext();MyHelloService myHelloService = (MyHelloService)ic.lookup("java:comp/env/service/MyJAXRPCHello");appclient.HelloIF helloPort = myHelloService.getHelloIFPort();((Stub)helloPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,args[0]);System.out.println(helloPort.sayHello("Jake!"));

Page 5: Jax Rpc Versus Jax Ws

Service Endpoint ModelJAX-RPC supports a client model for the service consumer, and a service endpoint model for the service producer.

Application-Level Interaction ModesJAX-RPC specifies three client application interaction models:* Synchronous request-response two-way RPC* Asynchronous (non-blocking) request-response two-way RPC* One-way RPC

JAX-WS

JAX-WS 2.0 is the successor of JAX-RPC 1.1 - the Java API for XML-based Web services. If possible, JAX-WS should be used instead as it is based on the most recent industry standards.

What remains the same?

Before we itemize the differences between JAX-RPC 1.1 and JAX-WS 2.0, we should first discuss what is the same.

Page 6: Jax Rpc Versus Jax Ws

* JAX-WS still supports SOAP 1.1 over HTTP 1.1, so interoperability will not be affected. The same messages can still flow across the wire.

* JAX-WS still supports WSDL 1.1, so what you've learned about that specification is still useful. A WSDL 2.0 specification is nearing completion, but it was still in the works at the time that JAX-WS 2.0 was finalized.

What is different?

* SOAP 1.2JAX-RPC and JAX-WS support SOAP 1.1. JAX-WS also supports SOAP 1.2.

* XML/HTTPThe WSDL 1.1 specification defined an HTTP binding, which is a means by which you can send XML messages over HTTP without SOAP. JAX-RPC ignored the HTTP binding. JAX-WS adds support for it.

* WS-I's Basic ProfilesJAX-RPC supports WS-I's Basic Profile (BP) version 1.0. JAX-WS supports BP 1.1. (WS-I is the Web services interoperability

Page 7: Jax Rpc Versus Jax Ws

organization.)

* New Java featureso JAX-RPC maps to Java 1.4. JAX-WS maps to Java 5.0. JAX-WS relies on many of the features new in Java 5.0.o Java EE 5, the successor to J2EE 1.4, adds support for JAX-WS, but it also retains support for JAX-RPC, which could be confusing to today's Web services novices.

* The data mapping modelo JAX-RPC has its own data mapping model, which covers about 90 percent of all schema types. Those that it does not cover are mapped to javax.xml.soap.SOAPElement.o JAX-WS's data mapping model is JAXB. JAXB promises mappings for all XML schemas.

* The interface mapping modelJAX-WS's basic interface mapping model is not extensively different from JAX-RPC's; however:o JAX-WS's model makes use of new Java 5.0 features.o JAX-WS's model introduces asynchronous functionality.

Page 8: Jax Rpc Versus Jax Ws

* The dynamic programming modelo JAX-WS's dynamic client model is quite different from JAX-RPC's. Many of the changes acknowledge industry needs:+ It introduces message-oriented functionality.+ It introduces dynamic asynchronous functionality.o JAX-WS also adds a dynamic server model, which JAX-RPC does not have.

* MTOM (Message Transmission Optimization Mechanism)JAX-WS, via JAXB, adds support for MTOM, the new attachment specification. Microsoft never bought into the SOAP with Attachments specification; but it appears that everyone supports MTOM, so attachment interoperability should become a reality.

* The handler modelo The handler model has changed quite a bit from JAX-RPC to JAX-WS.o JAX-RPC handlers rely on SAAJ 1.2. JAX-WS handlers rely on the new SAAJ 1.3 specification.

Page 9: Jax Rpc Versus Jax Ws

JAX-RPC versus JAX-WS

Introduction

Web services have been around a while now. First there was SOAP. But SOAP only described what the messages looked like. Then there was WSDL. But WSDL didn't tell you how to write web services in Java™. Then along came JAX-RPC 1.0. After a few months of use, the Java Community Process (JCP) folks who wrote that specification realized that it needed a few tweaks, so out came JAX-RPC 1.1. After a year or so of using that specification, the JCP folks wanted to build a better version: JAX-RPC 2.0. A primary goal was to align with industry direction, but the industry was not merely doing RPC web services, they were also doing message-oriented web services. So "RPC" was removed from the name and replaced with "WS" (which stands for web Services, of course). Thus the successor to JAX-RPC 1.1 is

Page 10: Jax Rpc Versus Jax Ws

JAX-WS 2.0 - the Java API for XML-based web services.

What remains the same?

Before we itemize the differences between JAX-RPC 1.1 and JAX-WS 2.0, we should first discuss what is the same.

JAX-WS still supports SOAP 1.1 over HTTP 1.1, so interoperability will not be affected. The same messages can still flow across the wire.

JAX-WS still supports WSDL 1.1, so what you've learned about that specification is still useful. A WSDL 2.0 specification is nearing completion, but it was still in the works at the time that JAX-WS 2.0 was finalized.

What is different?

SOAP 1.2

JAX-RPC and JAX-WS support SOAP 1.1. JAX-WS also supports SOAP 1.2.

XML/HTTP

The WSDL 1.1 specification defined an HTTP binding, which is a means by which you can send XML messages over HTTP

Page 11: Jax Rpc Versus Jax Ws

without SOAP. JAX-RPC ignored the HTTP binding. JAX-WS adds support for it.

WS-I's Basic Profiles

JAX-RPC supports WS-I's Basic Profile (BP) version 1.0. JAX-WS supports BP 1.1. (WS-I is the web services interoperability organization.)

New Java features o JAX-RPC maps to Java 1.4. JAX-WS

maps to Java 5.0. JAX-WS relies on many of the features new in Java 5.0.

o Java EE 5, the successor to J2EE 1.4, adds support for JAX-WS, but it also retains support for JAX-RPC, which could be confusing to today's web services novices.

The data mapping model o JAX-RPC has its own data mapping

model, which covers about 90 percent of all schema types. Those that it does not cover are mapped to javax.xml.soap.SOAPElement.

o JAX-WS's data mapping model is JAXB. JAXB promises mappings for all XML schemas.

The interface mapping model

Page 12: Jax Rpc Versus Jax Ws

JAX-WS's basic interface mapping model is not extensively different from JAX-RPC's; however:

o JAX-WS's model makes use of new Java 5.0 features.

o JAX-WS's model introduces asynchronous functionality.

The dynamic programming model o JAX-WS's dynamic client model is quite

different from JAX-RPC's. Many of the changes acknowledge industry needs:

It introduces message-oriented functionality.

It introduces dynamic asynchronous functionality.

o JAX-WS also adds a dynamic server model, which JAX-RPC does not have.

MTOM (Message Transmission Optimization Mechanism)

JAX-WS, via JAXB, adds support for MTOM, the new attachment specification. Microsoft never bought into the SOAP with Attachments specification; but it appears that everyone supports MTOM, so attachment interoperability should become a reality.

The handler model

Page 13: Jax Rpc Versus Jax Ws

o The handler model has changed quite a bit from JAX-RPC to JAX-WS.

o JAX-RPC handlers rely on SAAJ 1.2. JAX-WS handlers rely on the new SAAJ 1.3 specification.

In the remainder of this tip, we will discuss SOAP 1.2, XML/HTTP, the WS-I Basic Profiles, and Java 5. Each of the remaining five bullets above will be a separate tip in this series.

SOAP encodingSOAP encoding has fallen out of favor in the web services community. It is not supported by the WS-I basic profile. So JAX-WS, as the latest incarnation of Java web services, has disallowed SOAP encoding. JAX-RPC supports SOAP encoding, so if you really must use SOAP encoded messages, stick with JAX-RPC.

SOAP 1.2

There is really not a lot of difference, from a programming model point of view, between SOAP 1.1 and SOAP 1.2. As a Java programmer, the only place you will encounter these differences is when using the handlers, which we will cover in a future tip. SAAJ 1.3 has been updated to support SOAP 1.2.

XML/HTTP

Page 14: Jax Rpc Versus Jax Ws

Like the changes for SOAP 1.2, there is really not a lot of difference, from a programming model point of view, between SOAP/HTTP and XML/HTTP messages. As a Java programmer, the only place you will encounter these differences is when using the handlers, which we will cover in a future tip. The HTTP binding has its own handler chain and its own set of message context properties.

WS-I's basic profiles

JAX-RPC 1.1 supports WS-I's Basic Profile (BP) 1.0. Since that time, the WS-I folks have developed BP 1.1 (and the associated AP 1.0 and SSBP 1.0). These new profiles clarify some minor points, and more clearly define attachments. JAX-WS 2.0 supports these newer profiles. For the most part, the differences between them do not affect the Java programming model. The exception is attachments. WS-I not only cleared up some questions about attachments, but they also defined their own XML attachment type: wsi:swaRef.

Many people are confused by all these profiles. You will need a little history to clear up the confusion.

WS-I's first basic profile (BP 1.0) did a good job of clarifying the various specs. But it wasn't

Page 15: Jax Rpc Versus Jax Ws

perfect. And support for SOAP with Attachments (Sw/A) in particular was still rather fuzzy. In their second iteration, the WS-I folks pulled attachments out of the basic profile - BP 1.1 - and fixed some of the things they missed the first time around. At that point they also added two mutually exclusive supplements to the basic profile: AP 1.0 and SSBP 1.0. AP 1.0 is the Attachment Profile which describes how to use Sw/A. SSBP 1.0 is the Simple SOAP Binding Profile, which describes a web services engine that does not support Sw/A (such as Microsoft's .NET). The remaining profiles that WS-I has and is working on build on top of those basic profiles.

Java 5

There are a number of changes to the Java language. JAX-WS relies on: annotations, generics, and executors. We will detail exactly how JAX-WS relies on this new functionality in follow-on tips. For information on these new features of Java, see the Java 5 link in Resources.

Summary

JAX-WS 2.0 is the successor to JAX-RPC 1.1. There are some things that haven't changed, but most of the programming model is different to a greater or lesser degree. The topics

Page 16: Jax Rpc Versus Jax Ws

introduced in this tip will be expanded upon in a series of tips which we will publish over the coming months that will compare, in detail, JAX-WS and JAX-RPC. At a high level though, here are a few reasons why you would or would not want to move to JAX-WS from JAX-RPC.

Reasons you may want to stay with JAX-RPC 1.1:

If you want to stay with something that's been around a while, JAX-RPC will continue to be supported for some time to come.

If you don't want to step up to Java 5. If you want to send SOAP encoded

messages or create RPC/encoded style WSDL.

Reasons to step up to JAX-WS 2.0:

If you want to use the new message-oriented APIs.

If you want to use MTOM to send attachment data.

If you want better support for XML schema through JAXB.

If you want to use an asynchronous programming model in your web service clients.

If you need to have clients or services that can handle SOAP 1.2 messages.

Page 17: Jax Rpc Versus Jax Ws

If you want to eliminate the need for SOAP in your web services and just use the XML/HTTP binding.

If you like playing with leading edge technology.

Mapping XML schema to Java

JAX-RPC and JAXBWhy didn't JAX-RPC use JAXB in the first place? The answer is timing. The first version of JAX-RPC was completed before JAXB, so rather than wait, the writers of JAX-RPC developed their own mapping feature.

Mapping XML names to Java names in JAX-RPC and JAX-WS/JAXB are essentially the same, while mapping simple types has some slight differences. Table 1 shows these differences, which may appear significant; however, except for date/time types, they're the least-used XML simple types.

Table 1. Mapping differences between JAX-RPC 1.1 and JAXB 2.0 for XML simple types

Type JAX-RPC 1.1

JAXB 2.0

xsd:anySimpleType

java.lang.String

java.lang.Object

xsd:duration java.lang.String

javax.xml.datatype.Duration (new type)

xsd:dateTime

java.util.Calendar

javax.xml.datatype.XMLGregorianCalendar (new type)

xsd:time java.util.Caljavax.xml.datatype.XMLGre

Page 18: Jax Rpc Versus Jax Ws

endar gorianCalendar

xsd:date java.util.Calendar

javax.xml.datatype.XMLGregorianCalendar

xsd:gYearMonth

java.lang.String

javax.xml.datatype.XMLGregorianCalendar

xsd:gYear java.lang.String

javax.xml.datatype.XMLGregorianCalendar

xsd:gMonthDay

java.lang.String

javax.xml.datatype.XMLGregorianCalendar

xsd:gMonth java.lang.String

javax.xml.datatype.XMLGregorianCalendar

xsd:gDay java.lang.String

javax.xml.datatype.XMLGregorianCalendar

xsd:anyURI java.net.URI

java.lang.String

xsd:NMTOKENS

java.lang.String[]

java.util.List<java.lang.String>

xsd:IDREF java.lang.String

java.lang.Object

xsd:IDREFS java.lang.String[]

java.util.List<java.lang.Object>

xsd:ENTITY not supported

java.lang.String

xsd:ENTITIESnot supported

java.util.List<java.lang.String>

The pure Java aspects of the simple type mappings are nearly the same between JAX-RPC and JAXB, but the JAXB mappings also use the new Java annotation feature. See Listings 1 through 3 for some examples of simple type mappings.

Listing 1. XML complexType elements and attributes

Page 19: Jax Rpc Versus Jax Ws

<xsd:sequence> <xsd:element name="intField" type="xsd:int"/> <xsd:element name="intMinField" type="xsd:int" minOccurs="0"/> <xsd:element name="intNilField" type="xsd:int" nillable="true"/> <xsd:element name="stringField" type="xsd:string"/> <xsd:element name="stringMinField" type="xsd:string" minOccurs="0"/> <xsd:element name="stringNilField" type="xsd:string" nillable="true"/> </xsd:sequence> <xsd:attribute name="intAttr" type="xsd:int"/> <xsd:attribute name="intAttrReq" type="xsd:int" use="required"/>

Listing 2. Mapping to Java Bean properties via JAX-RPC 1.1

private int intField; private Integer intMinField; private Integer intNilField; private String stringField; private String stringMinField; private String stringNilField; private Integer intAtt; private int intAttReq;

Listing 3. Mapping to Java Bean properties via JAXB 2.0 protected int intField; protected Integer intMinField;

@XmlElement(required = true, type =

Page 20: Jax Rpc Versus Jax Ws

Integer.class, nillable = true) protected Integer intNilField;

@XmlElement(required = true) protected String stringField;

protected String stringMinField;

@XmlElement(required = true, nillable = true) protected String stringNilField;

@XmlAttribute protected Integer intAtt;

@XmlAttribute(required = true) protected int intAttReq;

In a JAX-RPC 1.1-generated Java Bean, you cannot tell the difference between:

An element field and an attribute field A field mapped from minOccurs="0"

type="xsd:int" and a field mapped from nillable="true" type="xsd:int"

A field mapped from type="xsd:string" and type="xsd:string" minOccurs="0"

But now you can, thanks to JAXB's use of new Java annotations. The @XmlElement and @XmlAttribute annotations have several parameters. The ones pertinent to this article include:

Required: Must the element exist? For example, is minOccurs something other than one?

Nillable: Does the field contain the nillable="true" attribute?

Page 21: Jax Rpc Versus Jax Ws

Mapping arrays

Mapping arrays from XML to Java differs between JAX-RPC and JAXB because JAXB uses the new generic Java feature, as Listings 4 through 6 show.

Listing 4. XML array <xsd:element name="intArrayField" type="xsd:int" minOccurs="0" maxOccurs="unbounded"/>

Listing 5. Mapping to Java Bean properties via JAX-RPC 1.1 private int[] intArrayField; public int[] getIntArrayField() {...} public void setIntArrayField(int[] intArrayField) {...} public int getIntArrayField(int i) {...} public void setIntArrayField(int i, int value) {...}

Listing 6. Mapping to Java Bean properties via JAXB 2.0 @XmlElement(type = Integer.class) protected List<Integer> intArrayField; public List<Integer> getIntArrayField() {...}

Notice the differences in the accessor methods. The JAX-RPC mapping follows the strict definition of Java Bean array accessors. The JAXB mapping does not map to an array, so it slightly differs.

Page 22: Jax Rpc Versus Jax Ws

getIntArrayField returns a reference, not just a snapshot, to the live list. Therefore, any modification you make to the returned list will be present inside the property. This is why no set method exists for 'array' properties.

Mapping complex types

Mapping a complexType is nearly the same between JAX-RPC and JAXB, except the fields are private in JAX-RPC and protected in JAXB, and the JAXB mapping adds annotations describing the field order. See Listings 7 through 9 for an example and comparisons between the two mappings.

Listing 7. XML schema complexType <xsd:element name="Phone" type="tns:Phone"/> <xsd:complexType name="Phone"> <xsd:sequence> <xsd:element name="areaCode" type="xsd:string"/> <xsd:element name="exchange" type="xsd:string"/> <xsd:element name="number" type="xsd:string"/> </xsd:sequence> </xsd:complexType>

Listing 8. JAX-RPC 1.1 mapping of complexType public class Phone { private String areaCode; private String exchange; private String number;

...

Page 23: Jax Rpc Versus Jax Ws

}

Listing 9. JAXB 2.0 mapping of complexType @XmlType(name = "Phone", propOrder = { "areaCode", "exchange", "number"})public class Phone {

@XmlElement(required = true) protected String areaCode; @XmlElement(required = true) protected String exchange; @XmlElement(required = true) protected String number;

...}

Note that the schema in Listing 7 used xsd:sequence. If it had used xsd:all instead, the propOrder annotation would have been empty: @XmlType(name = "Phone", propOrder = {}).

The new ObjectFactory class

JAXB generates a file that JAX-RPC does not: ObjectFactory. Each directory containing Java Beans will have one ObjectFactory. For each type defined in the schema's corresponding namespace, the ObjectFactory class will have a create method for that type. For each element, the ObjectFactory class will have a create element method, which returns a javax.xml.bind.JAXBElement<Type>. For example, for

Page 24: Jax Rpc Versus Jax Ws

the Phone schema in Listing 7, Listing 10 shows the generated ObjectFactory class with a method that returns an instance of Phone and a method that returns an instance of JAXBElement<Phone>. You can still directly instantiate the Java Beans in the directory, but it would be best to use the factory.

Listing 10. JAXB 2.0 ObjectFactory for Phoneimport javax.xml.bind.JAXBElement;import javax.xml.bind.annotation.XmlElementDecl;import javax.xml.namespace.QName;

public class ObjectFactory {

private final static QName _Phone_QNAME = new QName ("urn:types.MyServiceSample.ibm.com", "Phone");

public ObjectFactory() {...}

public Phone createPhone() {...}

@XmlElementDecl(namespace = "urn:types.MyServiceSample.ibm.com", name = "Phone") public JAXBElement<Phone> createPhone(Phone value) {...}}

Java to XML schema mappings

With a judicious sprinkling of these new JAXB-defined annotations, Java can map in a well-directed manner to XML, essentially in the reverse of the XML-to-Java mappings that we have presented. But what about unannotated Java?

Page 25: Jax Rpc Versus Jax Ws

Mapping Java names to XML names in JAX-RPC and JAXB are essentially the same. That is, Java primitive types map to the same XML schema whether the mapping follows JAX-RPC or JAXB. JAX-RPC defines a small set of standard Java classes that map to XML. For all but one of those, JAXB maps precisely the same, but JAXB adds a few more to its list of mapped classes, as Table 2 shows.

Table 2. Mapping differences between JAX-RPC 1.1 and JAXB 2.0 for standard Java classes

TypeJAX-RPC 1.1

JAXB 2.0

java.lang.String

xsd:string

xsd:string

java.math.BigInteger

xsd:integer

xsd:integer

java.math.BigDecimal

xsd:decimal

xsd:decimal

java.util.Calendar

xsd:dateTime

xsd:dateTime

java.util.Datexsd:dateTime

xsd:dateTime

javax.xml.namespace.QName

xsd:QName

xsd:QName

java.net.URI xsd:anyURI

xsd:string

javax.xml.datatype.

n/a xsd:anySimpleTyp

Page 26: Jax Rpc Versus Jax Ws

XMLGregorianCalendar

e

javax.xml.datatype.Duration

n/axsd:duration

java.lang.Object

n/a1xsd:anyType

java.awt.Image

n/a2xsd:base64Binary

javax.activation.DataHandler

n/a2xsd:base64Binary

javax.xml.transform.Source

n/a2xsd:base64Binary

java.util.UUID n/a xsd:string

Table 2 Notes:1. Some vendors mapped java.lang.Object to xsd:anyType.2. In JAX-RPC, this is mapped to a mime binding type - the XML type is undefined.

Conclusion

We've compared the mappings of JAX-RPC 1.1 and JAXB 2.0. They are similar with some notable exceptions:

XML to Java:o A few of the simple types are mapped

differentlyo JAXB adds the ObjectFactory class

Page 27: Jax Rpc Versus Jax Ws

o JAXB makes use of the new Java language annotation feature and generic feature

Java to XML:o The primitive type mappings are identicalo The standard Java mappings are nearly

identical

We can say much more about the JAXB 2.0 specification, particularly its use of Java annotations, but that topic is out of this article's scope. For more information about JAXB 2.0, see Resources.

Introduction

Overall, the structures of a Java API for XML-based RPC (JAX-RPC) 1.1 service endpoint interface (SEI) and a Java API for XML Web Services (JAX-WS) 2.0 SEI are very similar. This article addresses the differences. Even with differences in structure, however, the goal of providing an interface that reflects the contract of the Web service is the same.

Comparing SEI mapping

Listing 1 shows the WSDL for a simple HelloWorld Web service.

Listing 1. HelloWorld WSDL <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="urn:helloWorld/sample/ibm

Page 28: Jax Rpc Versus Jax Ws

/com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloWorld" targetNamespace="urn:helloWorld/sample/ibm/com"> <wsdl:types> <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com" xmlns:tns="urn:helloWorld/sample/ibm/com" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="hello"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="helloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="response" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types>

Page 29: Jax Rpc Versus Jax Ws

<wsdl:message name="helloRequestMsg"> <wsdl:part element="tns:hello" name="helloParameters" /> </wsdl:message> <wsdl:message name="helloResponseMsg"> <wsdl:part element="tns:helloResponse" name="helloResult" /> </wsdl:message> <wsdl:portType name="HelloWorld"> <wsdl:operation name="hello"> <wsdl:input message="tns:helloRequestMsg" name="helloRequest" /> <wsdl:output message="tns:helloResponseMsg" name="helloResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloWorldBinding" type="tns:HelloWorld"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="hello"> <soap:operation soapAction="urn:helloWorld/sample/ibm/com/hello" /> <wsdl:input name="helloRequest"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="helloResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation>

Page 30: Jax Rpc Versus Jax Ws

</wsdl:binding> <wsdl:service name="HelloWorldService"> <wsdl:port name="port" binding="tns:HelloWorldBinding"> <soap:address location="http://tempuri.org/" /> </wsdl:port> </wsdl:service></wsdl:definitions>

Listing 2 shows the JAX-RPC mapping of the Java SEI from this WSDL without the method signatures (you will see more about those later).

Listing 2. JAX-RPC HelloWorld SEI package com.ibm.samples;public interface HelloWorld extends java.rmi.Remote {...}

Listing 3 shows the JAX-WS SEI for the same WSDL.

Listing 3. JAX-WS HelloWorld SEI package com.ibm.samples.helloworld;

import javax.jws.WebService;

@WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld")public interface HelloWorld {

Page 31: Jax Rpc Versus Jax Ws

...}

There are three differences here:

Package: The target namespace is "urn:helloWorld/sample/ibm/com". Both mappings take the domain name-like string and reverse the order of the elements. JAX-RPC's mapping stops at the first slash. JAX-WS's mapping continues with the string, adding the information after the first slash. Both specifications allow for custom namespace-to-package mappings.

Annotations: JAX-WS requires that all SEIs include the @WebService annotation. As mentioned in Part 1 of this series, JAX-WS includes support for the annotations defined in JSR-181 Web Services Metadata.

java.rmi.Remote: The JAX-RPC SEI extends the java.rmi.Remote interface. JAX-WS no longer requires this.

Before moving into the details of operation mappings, there is one last thing about the SEI itself. Although JAX-WS provides support for Web services that have an SEI, this is not mandatory for all services. With JAX-WS, a JavaBean can be deployed on its own as a Web service implementation, as opposed to JAX-RPC where the bean must include an SEI. JAX-WS services deployed without an SEI are considered to have an implicit SEI.

Page 32: Jax Rpc Versus Jax Ws

Comparing operation mapping

Now that you have seen the interfaces, look at the comparison of how the operations are mapped. There are different ways of designing a WSDL document to represent Web services that have similar semantics. The article Which style of WSDL should I use? provides an overview of the different styles of WSDL documents available and how to determine which is best for you.

Now, look at how JAX-RPC and JAX-WS map to each of the WSDL styles.

Exploring the document/literal wrapped pattern

The WSDL in Listing 1 is formatted using the document/literal wrapped pattern. Listings 4 and 5 are mappings for the same wrapped operation in JAX-RPC and JAX-WS. Notice that JAX-WS adds the @RequestWrapper and @ResponseWrapper annotations to the method. These provide additional metadata about both the elements that will serve as the operation wrapper along with any Java beans that might have been generated for those wrapper elements. These annotations are optional.

Listing 4. JAX-RPC complete HelloWorld SEI package com.ibm.samples;

public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello(java.lang.String name) throws java.rmi.RemoteException;

Page 33: Jax Rpc Versus Jax Ws

}

Listing 5. JAX-WS complete HelloWorld SEI package com.ibm.samples.helloworld;

import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import javax.xml.ws.RequestWrapper;import javax.xml.ws.ResponseWrapper;

@WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld")public interface HelloWorld {

@WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello") @WebResult(name = "response", targetNamespace = "") @RequestWrapper(localName = "hello", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.Hello") @ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.HelloResponse") public String hello( @WebParam(name = "name", targetNamespace = "")

Page 34: Jax Rpc Versus Jax Ws

String name);}

As you can see, the JAX-WS mapping again has a lot of annotations, but when you get down to the root signature, the only difference is that the JAX-RPC method can throw java.rmi.RemoteException while the JAX-WS method is not defined to do so.

Exploring document/literal patterns

Both JAX-RPC and JAX-WS support mapping operations that are document/literal, but are not wrapped. To accomplish this with the HelloWorld sample, you would need to remove the wrapper elements that represent the operation name. Listing 6 shows what the relevant portions of the WSDL document would look like in comparison to the WSDL in Listing 1.

Listing 6. Document/literal WSDL <wsdl:types> <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com" xmlns:tns="urn:helloWorld/sample/ibm/com" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="hello" type="xsd:string"/> <xsd:element name="helloResponse"

Page 35: Jax Rpc Versus Jax Ws

type="xsd:string"/> </xsd:schema></wsdl:types>

<wsdl:message name="helloRequestMsg"> <wsdl:part element="tns:hello" name="helloParameters" /></wsdl:message>

<wsdl:message name="helloResponseMsg"> <wsdl:part element="tns:helloResponse" name="helloResult" /></wsdl:message>

Now look at the Java mapping for this new WSDL. Listings 7 and 8 show the JAX-RPC and JAX-WS mappings respectively. Do you see how similar the JAX-RPC mapping is? The only difference is the parameter name. As with the previous case, putting the annotations aside, there is no real difference between the JAX-RPC mapping and the JAX-WS mapping.

Listing 7. JAX-RPC document/literal mapping public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello(java.lang.String helloParameters) throws java.rmi.RemoteException;}

Page 36: Jax Rpc Versus Jax Ws

Listing 8. JAX-WS document/literal mapping @WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")@SOAPBinding(parameterStyle = ParameterStyle.BARE)public interface HelloWorld {

@WebMethod(action = "urn:helloWorld/sample/ibm/com/hello") @WebResult(name = "helloResponse", targetNamespace = "urn:helloWorld/sample/ibm/com", partName = "helloResult") public String hello( @WebParam(name = "hello", targetNamespace = "urn:helloWorld/sample/ibm/com", partName = "helloParameters") String helloParameters);

}

Notice that for JAX-WS, you no longer see the @RequestWrapper and @ResponseWrapper annotations. Also note that a new annotation appears at the interface level as well, @SOAPBinding. This annotation provides information about the parameter style. If absent, the default value for the parameterStyle attribute is wrapped, which would be like the WSDL in Listing 1.

Page 37: Jax Rpc Versus Jax Ws

Exploring the RPC/literal patterns

The next example is somewhat different from the previous two. With an RPC/literal style WSDL, the parts are defined in terms of types rather than elements. Listing 9 contains the relevant WSDL differences.

Listing 9. RPC/literal WSDL changes <wsdl:types/>

<wsdl:message name="helloRequestMsg"> <wsdl:part name="helloParameters" type="xsd:string"/></wsdl:message>

<wsdl:message name="helloResponseMsg"> <wsdl:part name="helloResult" type="xsd:string"/></wsdl:message>

The Java mappings in Listings 10 and 11 reflect the changes to the WSDL. Again, you see an identical mapping when the annotations are stripped away.

Listing 10. JAX-RPC RPC/literal mapping public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello(java.lang.String helloParameters)

Page 38: Jax Rpc Versus Jax Ws

throws java.rmi.RemoteException;}

Listing 11. JAX-WS RPC/Literal mapping @WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")@SOAPBinding(style = Style.RPC)public interface HelloWorld {

@WebMethod(action = "urn:helloWorld/sample/ibm/com/hello") @WebResult(name = "helloResult", partName = "helloResult") public String hello( @WebParam(name = "helloParameters", partName = "helloParameters") String helloParameters);

}

Comparing this JAX-WS interface to the previous, you see that the @SOAPBinding annotation remains, but now it is not used for the parameter style, but rather the WSDL style.

Exploring the RPC/encoded patterns

There is no comparison for RPC/encoded style operations that can be made. JAX-WS does not support any mappings for WSDL documents that contain an encoded representation for the data. This

Page 39: Jax Rpc Versus Jax Ws

comes from JAX-WS's compliance with WS-I's Basic Profile 1.1, which does not allow usage of encoded WSDL documents. There are good reasons to build an RPC/encoded Web service, in which case you should stick with the JAX-RPC mappings, but if you want to write interoperable Web services, you should not use RPC/encoded.

Considering other differences

A major difference in operation mapping for JAX-WS over JAX-RPC is the introduction of asynchronous operations. Any WSDL operation with a two-way message flow, or one where the client expects to receive a response, can be mapped to an asynchronous Java representation. There are two different mechanisms, asynchronous with a callback and asynchronous polling, that require two different mappings. A future article will describe how these two types of operations work. This article just shows you an example. Listing 12 contains an asynchronous callback operation, where the javax.xml.ws.AsyncHandler object is the callback object. Listing 13 contains an asynchronous polling operation mapping.

Listing 12. JAX-WS asynchronous callback @WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")@RequestWrapper(localName = "hello", targetNamespace =

Page 40: Jax Rpc Versus Jax Ws

"urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.Hello")@ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.HelloResponse")public Future<?> helloAsync( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "asyncHandler", targetNamespace = "") AsyncHandler<String> asyncHandler);

Listing 13. JAX-WS asynchronous polling @WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")@RequestWrapper(localName = "hello", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.Hello")@ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:samples.ibm.com/HelloWorld", className = "com.ibm.samples.helloworld.HelloResponse")public Response<String> helloAsync( @WebParam(name = "name",

Page 41: Jax Rpc Versus Jax Ws

targetNamespace = "") String name);

There is no asynchronous mapping for WSDL operations in JAX-RPC, so you do not have anything to make a comparison to here. One important note, however, is that the asynchronous mappings only apply to the client side. No such asynchronous mappings exist for service endpoints, only for clients.

Comparing IN/OUT parameters

Both JAX-RPC and JAX-WS support parameters known as IN/OUT parameters. In Listing 14, you see an IN/OUT parameter added to the WSDL from Listing 1. Notice that the parameter with the name "inout" appears in both the input and the output. In this scenario, both JAX-RPC and JAX-WS map that parameter to a holder parameter, but the impact this has is different for each mapping.

Listing 14. A WSDL with an IN/OUT parameter <xsd:element name="hello"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" nillable="true" type="xsd:string" /> <xsd:element name="inout" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType></xsd:element>

<xsd:element name="helloResponse"> <xsd:complexType>

Page 42: Jax Rpc Versus Jax Ws

<xsd:sequence> <xsd:element name="response" nillable="true" type="xsd:string" /> <xsd:element name="inout" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType></xsd:element>

Listing 15 has the JAX-RPC mapping for a holder parameter, and Listing 16 has the JAX-WS mapping.

Listing 15. JAX-RPC SEI with IN/OUT parameters public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello( java.lang.String name, javax.xml.rpc.holders.StringHolder inout) throws java.rmi.RemoteException;}

Listing 16. JAX-WS SEI with IN/OUT parameters @WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")public interface HelloWorld {

@WebMethod(action = "urn:helloWorld/sample/ibm/com/hello") @RequestWrapper(localName = "hello",

Page 43: Jax Rpc Versus Jax Ws

targetNamespace = "urn:helloWorld/sample/ibm/com", className = "helloworld.sample.ibm.com.Hello") @ResponseWrapper(localName = "helloResponse", targetNamespace = "urn:helloWorld/sample/ibm/com", className = "helloworld.sample.ibm.com.HelloResponse") public void hello( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "inout", targetNamespace = "", mode = Mode.INOUT) Holder<String> inout, @WebParam(name = "response", targetNamespace = "", mode = Mode.OUT) Holder<String> response);

}

For JAX-RPC, there are a set of classes defined by the specification as holder classes for known types. These include types like java.lang.String and other primitive types. For user defined types, JAX-RPC requires that custom holder classes be generated that can handle the user-defined types. JAX-WS, on the other hand, makes use of the Generics feature in Java 5 to provide a single class that can work for all types, including user-defined types.

Page 44: Jax Rpc Versus Jax Ws

Another interesting thing to note here is the difference in return types. Rather than keeping the return type as JAX-RPC does, JAX-WS makes the method void and makes use of the holder for what was the return value. By rule in JAX-WS, when there is more than one parameter that can be considered an OUT parameter for an operation, the return type must be void, and all OUT parameters are mapped to holder types.

Summary

The above examples illustrate that, while there are a number of differences between JAX-RPC and JAX-WS, the mapping from WSDL to the structure of a service endpoint interface is very similar. The key differences are:

The package names are different.

JAX-RPC requires java.rmi.Remote and java.rmi.RemoteException, which JAX-WS does not.

Holders are defined differently.

Even with all the similarities that exist, there is one major difference that makes the JAX-WS SEI a very different entity from the JAX-RPC one. The use of JSR-181 annotations gives the JAX-WS SEI the capability to not only represent the Java-centric view of the Web service, but also the WSDL-centric view. A number of the annotations included are used to map the Java information back to WSDL constructs. This information does not exist in any form in a JAX-RPC

Page 45: Jax Rpc Versus Jax Ws

SEI. Some of the other things that are exclusive to JAX-WS are the asynchronous invocation model and the fact that it does not require a generated SEI in the first place. On the other hand, JAX-RPC has something that JAX-WS does not: it supports an RPC/encoded WSDL.

Introduction

Both the JAX-RPC 1.1 and the JAX-WS 2.0 client dynamic model have a similar set of high-level steps to make an invocation:

1. Define the service.2. Create the dynamic invocation object from this

service.3. Build the message.4. Invoke the operation.

Even though both models follow these same steps, this tip describes how different the details between the two models are. You'll use the HelloWorld Web Services Description Language (WSDL) that you used in the previous tip. You can find it here in Listing 1.

Listing 1. HelloWorld service's WSDL <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="urn:helloWorld/sample/ibm/com" xmlns:wsdl="http://schemas.xmlsoap.o

Page 46: Jax Rpc Versus Jax Ws

rg/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloWorld" targetNamespace="urn:helloWorld/sample/ibm/com"> <wsdl:types> <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com" xmlns:tns="urn:helloWorld/sample/ibm/com" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="hello"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="helloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="response" nillable="true" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="helloRequestMsg"> <wsdl:part element="tns:hello"

Page 47: Jax Rpc Versus Jax Ws

name="helloParameters" /> </wsdl:message> <wsdl:message name="helloResponseMsg"> <wsdl:part element="tns:helloResponse" name="helloResult" /> </wsdl:message> <wsdl:portType name="HelloWorld"> <wsdl:operation name="hello"> <wsdl:input message="tns:helloRequestMsg" name="helloRequest" /> <wsdl:output message="tns:helloResponseMsg" name="helloResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloWorldBinding" type="tns:HelloWorld"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="hello"> <soap:operation soapAction="urn:helloWorld/sample/ibm/com/hello" /> <wsdl:input name="helloRequest"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="helloResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloWorldService">

Page 48: Jax Rpc Versus Jax Ws

<wsdl:port name="port" binding="tns:HelloWorldBinding"> <soap:address location="http://tempuri.org/" /> </wsdl:port> </wsdl:service> </wsdl:definitions>

Back to top

JAX-RPC's dynamic Call interface

JAX-RPC's dynamic invocation interface (DII) is the Call object (javax.xml.rpc.Call). Listing 2 contains a complete client main class that calls Listing 1's HelloWorld service using the Call object. You can also see the high-level steps described in the introduction in Listing 2.

Listing 2. JAX-RPC's DII client package com.ibm.samples.dii;

import javax.xml.namespace.QName;import javax.xml.rpc.Call;import javax.xml.rpc.ParameterMode;import javax.xml.rpc.Service;import javax.xml.rpc.ServiceFactory;import javax.xml.rpc.encoding.XMLType;

public class HelloWorldClient {

public static void main(String[] args) { try {

Page 49: Jax Rpc Versus Jax Ws

// Define the service. QName serviceName = new QName( "urn:helloWorld/sample/ibm/com", "HelloWorldService"); ServiceFactory factory = ServiceFactory.newInstance(); Service service = factory.createService(serviceName);

// Create the dynamic invocation object from this service. Call call = service.createCall(); call.setTargetEndpointAddress( "http://localhost:9081/HelloWorldService/services/port");

// Build the message. QName operationName = new QName( "urn:helloWorld/sample/ibm/com", "hello"); call.setOperationName(operationName); call.addParameter( "name", // parameter name XMLType.XSD_STRING, // parameter XML type QName String.class, // parameter Java type class

Page 50: Jax Rpc Versus Jax Ws

ParameterMode.IN); // parameter mode call.setReturnType(XMLType.XSD_STRING); call.setProperty( Call.OPERATION_STYLE_PROPERTY, "wrapped");

// Invoke the operation. Object[] actualArgs = {"Georgia"}; String response = (String) call.invoke(actualArgs); System.out.println("response = " + response); } catch (Throwable t) { t.printStackTrace(); } } }

Let's look at the details of those high-level steps:

1. Define the service. Using the fully qualified name of the WSDL's service, you construct a javax.xml.rpc.Service object.

2. Create the dynamic invocation object from this service. In JAX-RPC, the dynamic invocation object is javax.xml.rpc.Call.

3. Build the message. In this step, you populate the Call object with information about the operation. There's one thing to point out here: We call

Page 51: Jax Rpc Versus Jax Ws

call.setProperty(Call.OPERATION_STYLE_PROPERTY, "wrapped"); . wrapped is not a value defined by JAX-RPC for this property. JAX-RPC defines only rpc and document. However, rpc really means RPC/encoded, and document really means document/literal, non-wrapped. The document/literal wrapped pattern has become the industry standard since JAX-RPC was written, so its Call object doesn't deal well with it. You can do it, but it's not pretty. Extending this property to include the wrapped value is IBM's way of filling this gap of the specification, but it's a nonstandard extension.

4. Invoke the operation. The input in this example is a simple string, so you populate the argument array with a string and pass it to the invoke function. The response is also a string, and in this example you simply display it.

JAX-WS's dynamic Dispatch interface

JAX-WS's DII is the Dispatch object (javax.xml.ws.Dispatch). Listing 3 contains a complete client main class that calls Listing 1's HelloWorld service via this Dispatch object. You can see the high-level steps described in the introduction in Listing 3.

Listing 3. JAX-WS's DII client import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import javax.xml.namespace.QName;import javax.xml.transform.Source;

Page 52: Jax Rpc Versus Jax Ws

import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;import javax.xml.ws.Dispatch;import javax.xml.ws.Service;import javax.xml.ws.soap.SOAPBinding;

public class HelloWorldClient {

public static void main(String[] args) { try { // Define the service. QName svcQname = new QName( "urn:helloWorld/sample/ibm/com", "HelloWorldService"); QName portQName = new QName( "urn:helloWorld/sample/ibm/com", "port"); Service svc = Service.create(svcQname); svc.addPort( portQName, SOAPBinding.SOAP11HTTP_BINDING,

Page 53: Jax Rpc Versus Jax Ws

"http://localhost:9080/JAXBSampleWebService/HelloWorldService");

// Create the dynamic invocation object from this service. Dispatch<Source> dispatch = svc.createDispatch( portQName, Source.class, Service.Mode.PAYLOAD);

// Build the message. String content = "<ns2:hello xmlns:ns2=\"urn:helloWorld/sample/ibm/com\">" + "<name>Georgie</name>" + "</ns2:hello>"; ByteArrayInputStream bais = new ByteArrayInputStream(content.getBytes()); Source input = new StreamSource(bais);

// Invoke the operation. Source output = dispatch.invoke(input);

// Process the response. StreamResult result = new StreamResult(new ByteArrayOutputStream()); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.transform(response, result);

Page 54: Jax Rpc Versus Jax Ws

ByteArrayOutputStream baos = (ByteArrayOutputStream) result.getOutputStream();

// Write out the response content. String responseContent = new String(baos.toByteArray()); System.out.println(responseContent); } catch (Throwable t) { t.printStackTrace(); } }}

Let's look at the details of those high-level steps in this JAX-WS dynamic client:

1. Define the service. Like in JAX-RPC's model, you define the service based on its fully qualified name, but you also define the port within that service.

2. Create the dynamic invocation object from this service. In JAX-WS, the dynamic invocation object is javax.xml.ws.Dispatch. This class leverages the new Generics feature in Java 5 to support multiple parameter types.

3. Build the message. Here you build the raw SOAP message body contents.

4. Invoke the operation. You send the contents of the SOAP body to the service and receive the SOAP response back from the service.

Page 55: Jax Rpc Versus Jax Ws

Back to top

The differences between the models

Looking at the high-level steps, it appears that the dynamic invocation model for JAX-RPC and JAX-WS are similar. But this is somewhat misleading. When you look at the details of each example, you can see that the models are, in fact, very different. Let's take a look at some of those differences a little more closely.

Operation style

It should be fairly clear that the primary difference between the models is that JAX-RPC follows a remote procedure call (RPC) model (hence the RPC in the specification name), while JAX-WS's dynamic client follows a messaging model. With JAX-RPC, the Call object must be configured to explicitly invoke a particular operation from the WSDL. In JAX-WS, the Dispatch object is unaware of what operation is being invoked and is just sending XML data.

Parameter style

With JAX-RPC, the parameter type(s) passed retain the XML Schema-to-Java mappings that are defined by the specification. With JAX-WS, there are two different ways to use the Dispatch object: either as an XML-based Dispatch (as shown in this tip) or as a JAXB-based Dispatch. The XML-based Dispatch accepts parameters that are based on these object types: javax.xml.transform.Source, javax.xml.soap.SOAPMessage, and javax.activation.DataSource. The JAXB-based

Page 56: Jax Rpc Versus Jax Ws

Dispatch requires the user to configure a javax.xml.bind.JAXBContext that can be used to marshall and unmarshall instances of the parameters, which are JAXB Java beans.

Another major difference in the parameter style is in what the content passed in represents. For JAX-RPC, the parameter(s) always form the parameter data of the request. With JAX-WS, there are two different parameter modes: PAYLOAD and MESSAGE mode. PAYLOAD mode means the parameter represents just the contents of the SOAP body, where MESSAGE mode means the parameter represents the entire message, including the SOAP envelope.

Invocation patterns

As shown above, JAX-RPC and JAX-WS both provide a synchronous two-way invocation via the invoke() method. Both models also provide a method for invoking one-way Web service operations via the invokeOneWay method. A major difference between the two models is that JAX-WS also provides an asynchronous invocation model. There is an asynchronous callback model and an asynchronous polling model. JAX-RPC doesn't provide an option for asynchronous invocations.

Server-side dynamic programming model

Another major difference, which isn't covered in detail here, is that JAX-WS adds what JAX-RPC never had — a dynamic server-side programming model. Like the client-side model, it too can be configured for PAYLOAD or MESSAGE mode.

Page 57: Jax Rpc Versus Jax Ws

Back to top

Summary

Both JAX-RPC and JAX-WS provide a dynamic client model. And both can be viewed as equivalent from a high-level point of view. But when you get down to the details, you can see that JAX-RPC's dynamic model is an RPC model, while JAX-WS's dynamic model is a messaging model. The JAX-WS APIs provide greater flexibility and are the next step in the evolution of Web services programming models. JAX-WS also adds support for asynchronous support and for a dynamic service, which JAX-RPC doesn't define.

Introduction

The attachment model for JAX-RPC is Sw/A. Since JAX-RPC was written, a new attachment model has come onto the scene: MTOM. JAX-WS provides Sw/A support just as JAX-RPC does, but adds support for MTOM. JAX-WS supports MTOM via the Java Architecture for XML Binding (JAXB) specification, which includes APIs for marshalling and unmarshalling both Sw/A and MTOM attachments. In this tip, you examine both models through examples. Note: This tip compares only the WSDLs and the Java programming models; comparing the wire-level messages is left as an exercise to the reader.

Back to top

Page 58: Jax Rpc Versus Jax Ws

JAX-RPC and Sw/A example

Listing 1 shows the WSDL from an attachment tip written a few years ago (see Resources). Listing 2 shows the Java interface, which the JAX-RPC mapping produces from this WSDL.

Listing 1. JAX-RPC Sw/A WSDL<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://attachment.tip/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://attachment.tip/"> <types/> <message name="sendImage"> <part name="image" type="xsd:base64Binary"/> </message> <message name="sendImageResponse"/> <message name="sendOctet"> <part name="octet" type="xsd:base64Binary"/> </message> <message

Page 59: Jax Rpc Versus Jax Ws

name="sendOctetResponse"/> <portType name="AttachmentTip"> <operation name="sendImage"> <input message="tns:sendImage"/> <output message="tns:sendImageResponse"/> </operation> <operation name="sendOctet"> <input message="tns:sendOctet"/> <output message="tns:sendOctetResponse"/> </operation> </portType> <binding name="AttachmentBinding" type="tns:AttachmentTip"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sendImage"> <soap:operation soapAction=""/> <input> <mime:multipartRelated> <mime:part> <soap:body parts="" namespace="http://attachment.tip/" use="literal"/> </mime:part> <mime:part> <mime:content part="image" type="image/jpeg"/> </mime:part> </mime:multipartRelated> </input> <output> <soap:body namespace="http://attachment.tip/" use="literal"/>

Page 60: Jax Rpc Versus Jax Ws

</output> </operation> <operation name="sendOctet"> <soap:operation soapAction=""/> <input> <mime:multipartRelated> <mime:part> <soap:body parts="" namespace="http://attachment.tip/" use="literal"/> </mime:part> <mime:part> <mime:content part="octet" type="application/octet-stream"/> </mime:part> </mime:multipartRelated> </input> <output> <soap:body namespace="http://attachment.tip/" use="literal"/> </output> </operation> </binding> <service name="AttachmentService"> <port binding="tns:AttachmentBinding" name="AttachmentTip"> <soap:address location="http://localhost:9080/SwAService/services/AttachmentTip"/> </port> </service> </definitions>

Listing 2. JAX-RPC Sw/A Java interfacepackage tip.attachment;

Page 61: Jax Rpc Versus Jax Ws

import java.awt.Image;import java.rmi.Remote;import java.rmi.RemoteException;

import javax.activation.DataHandler;

public interface AttachmentTip extends Remote { public void sendImage(Image image) throws RemoteException; public void sendOctet(DataHandler octet) throws RemoteException;}

The Java interface mapping from the WSDL is fairly straightforward: The sendImage operation's image/jpeg part is mapped to a java.awt.Image parameter; the sendOctet operation's application/octet-stream is mapped to a javax.activation.DataHandler parameter. However, there's a cost to this mapping: The Multipurpose Internet Mail Extensions (MIME) type information isn't in the interface portion of the WSDL (the portType, message, and types sections). You must dip into the binding to find the MIME information. This is unfortunate because different bindings for the same WSDL interface could result in different types and, therefore, map to different Java interfaces. It would be better if there were a one-to-one mapping from WSDL interface to Java interface. If you have more than one binding, each simply maps to an implementation, all of which implements the same Java interface. With Sw/A, you can't do that; the mapping from WSDL to Java interfaces is not one to one.

Page 62: Jax Rpc Versus Jax Ws

A secondary issue with Sw/A is that it doesn't lend itself well to the industry convention of document/literal wrapped WSDL (you'll notice that the WSDL in Listing 1 is an rpc/literal WSDL). Adding Sw/A content to a document/literal wrapped message requires specifying additional message parts beyond the single operation wrapper.

Does MTOM fix these issues? Let's move on to the next section to find out.

Back to top

JAX-WS and MTOM example

In Listing 3, we've modified the Sw/A WSDL from Listing 1 to produce an equivalent MTOM WSDL.

Listing 3. JAX-WS MTOM WSDL<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://attachment.tip/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://attachment.tip/"> <types/>

Page 63: Jax Rpc Versus Jax Ws

<message name="sendImage"> <part name="image" type="xsd:base64Binary"/> </message> <message name="sendImageResponse"/> <message name="sendOctet"> <part name="octet" type="xsd:base64Binary"/> </message> <message name="sendOctetResponse"/> <portType name="AttachmentTip"> <operation name="sendImage"> <input message="tns:sendImage"/> <output message="tns:sendImageResponse"/> </operation> <operation name="sendOctet"> <input message="tns:sendOctet"/> <output message="tns:sendOctetResponse"/> </operation> </portType> <binding name="AttachmentBinding" type="tns:AttachmentTip"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sendImage"> <soap:operation soapAction=""/> <input> <soap:body namespace="http://attachment.tip/" use="literal"/> </input> <output>

Page 64: Jax Rpc Versus Jax Ws

<soap:body namespace="http://attachment.tip/" use="literal"/> </output> </operation> <operation name="sendOctet"> <soap:operation soapAction=""/> <input> <soap:body namespace="http://attachment.tip/" use="literal"/> </input> <output> <soap:body namespace="http://attachment.tip/" use="literal"/> </output> </operation> </binding> <service name="AttachmentService"> <port binding="tns:AttachmentBinding" name="AttachmentTip"> <soap:address location="http://localhost:9080/MTOMService/services/AttachmentTip"/> </port> </service></definitions>

The only real difference between the MTOM WSDL in Listing 3 and the Sw/A WSDL in Listing 1 is the binding. The MTOM binding contains no MIME information. In fact, there's no way to tell, from the WSDL, that you're dealing with attachments; the WSDL's binding looks like a normal binding.

Page 65: Jax Rpc Versus Jax Ws

Listing 4 shows the Java interface, which a JAX-WS mapping produces from this WSDL.

Listing 4. JAX-WS MTOM Java interfacepackage tip.attachment;

import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebService;import javax.jws.soap.SOAPBinding;

@WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/")@SOAPBinding(style = SOAPBinding.Style.RPC)public interface AttachmentTip {

@WebMethod public void sendImage( @WebParam(name = "image", partName = "image") byte[] image);

@WebMethod public void sendOctet( @WebParam(name = "octet", partName = "octet") byte[] octet);

}

Because the WSDL is a normal-looking WSDL with no hint of attachments, you end up with a Java interface that reflects that as well. Given parts of type base64Binary (or hexBinary), JAX-WS maps those to

Page 66: Jax Rpc Versus Jax Ws

parameters of type byte[]. With MTOM, the MIME-ness of the types has all been extracted from the WSDL with the burden placed on the client or server run time to format the content appropriately.

Back to top

Comparison of Sw/A and MTOM

The JAX-RPC Sw/A section noted two drawbacks to Sw/A:

The MIME type info is in the WSDL binding, not the WSDL interface.

It's difficult to create a document/literal wrapped attachment WSDL.

Let's discuss the document/literal wrapped style first.

document/literal wrapped style and attachments

We left the MTOM WSDL in Listing 3 as rpc/literal WSDL for comparison purposes; but it's an easy matter to turn this WSDL into document/literal wrapped WSDL. Listing 5 in the next section shows the document/literal wrapped equivalent of the WSDL in Listing 3 (see Resources for more information about the differences between various WSDL styles).

MIME type info in the binding

Because the MTOM WSDL's binding doesn't have any MIME information, you don't have to dip into the binding to determine the part types. You have everything you need in the WSDL interface to

Page 67: Jax Rpc Versus Jax Ws

generate the Java interface. However, as you can see by comparing the Java interfaces in Listing 2 and Listing 4, we've lost some information.

The interface portion of both WSDLs shows that the data type in the operations is base64Binary, which maps to byte[]. In the JAX-RPC Sw/A WSDL, however, you know from the binding that the part types are a MIME image and a MIME octet stream. In the JAX-WS MTOM WSDL, this information is lost. This may seem like a bad thing, but the positive spin is that this completely cleans up the interface. No matter what the binding, the interface is always the same. In fact, the implementors of the client and the server codebases shouldn't be bothered with the notion of whether the parameter is an attachment. That's merely a detail of the SOAP message, and the writers of the WSDL-to-Java mappings have tried their best to abstract the programmer away from the details of the SOAP message.

However, if you really want to know what the MIME type is—if you want to get back to the information you lost—JAX-WS provides support for an attribute that you can inject into an XML element: expectedContentTypes. This special attribute is highlighted in Listing 5. Listing 6 shows the corresponding Java interface. Ignoring the annotations, this Java interface is essentially the same as the interface in Listing 2.

Listing 5. JAX-WS MIME attribute<definitions

Page 68: Jax Rpc Versus Jax Ws

xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://attachment.tip/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://attachment.tip/"> <types> <xsd:schema xmlns:tns="http://attachment.tip/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://attachment.tip/"> <xsd:element name="sendImage" type="tns:sendImage"/> <xsd:complexType name="sendImage"> <xsd:sequence> <xsd:element xmlns:ns1="http://www.w3.org/2005/05/xmlmime"ns1:expectedContentTypes="image/*" name="image" type="xsd:base64Binary"/> </xsd:sequence> </xsd:complexType> <xsd:element name="sendImageResponse" type="tns:sendImageResponse"/>

Page 69: Jax Rpc Versus Jax Ws

<xsd:complexType name="sendImageResponse"> <xsd:sequence/> </xsd:complexType> <xsd:element name="sendOctet" type="tns:sendOctet"/> <xsd:complexType name="sendOctet"> <xsd:sequence> <xsd:element xmlns:ns1="http://www.w3.org/2005/05/xmlmime"ns1:expectedContentTypes="application/octet-stream" name="octet" type="xsd:base64Binary"/> </xsd:sequence> </xsd:complexType> <xsd:element name="sendOctetResponse" type="tns:sendOctetResponse"/> <xsd:complexType name="sendOctetResponse"> <xsd:sequence/> </xsd:complexType> </xsd:schema> </types> <message name="sendImage"> <part name="parameters" element="tns:sendImage"/> </message> <message name="sendImageResponse"> <part name="parameters" element="tns:sendImageResponse"/> </message> <message name="sendOctet"> <part name="parameters" element="tns:sendOctet"/> </message> <message name="sendOctetResponse">

Page 70: Jax Rpc Versus Jax Ws

<part name="parameters" element="tns:sendOctetResponse"/> </message> <portType name="AttachmentTip"> <operation name="sendImage"> <input message="tns:sendImage"/> <output message="tns:sendImageResponse"/> </operation> <operation name="sendOctet"> <input message="tns:sendOctet"/> <output message="tns:sendOctetResponse"/> </operation> </portType> <binding name="AttachmentBinding" type="tns:AttachmentTip"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sendImage"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> <operation name="sendOctet"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/>

Page 71: Jax Rpc Versus Jax Ws

</output> </operation> </binding> <service name="AttachmentService"> <port binding="tns:AttachmentBinding" name="AttachmentTip"> <soap:address location="http://localhost:9080/MTOMService/services/AttachmentTip"/> </port> </service></definitions>

Notice that this new attribute is wholly contained within the WSDL interface. It's not in the binding, so all of the type information is where you want it.

Listing 6. JAX-WS Java interface mapped from the MIME attributepackage tip.attachment;

import java.awt.Image;import javax.activation.DataHandler;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebService;import javax.xml.ws.RequestWrapper;import javax.xml.ws.ResponseWrapper;

@WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/")public interface AttachmentTip {

@WebMethod @RequestWrapper(localName =

Page 72: Jax Rpc Versus Jax Ws

"sendImage", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendImage") @ResponseWrapper(localName = "sendImageResponse", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendImageResponse") public void sendImage( @WebParam(name = "image", targetNamespace = "") Image image);

@WebMethod @RequestWrapper(localName = "sendOctet", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendOctet") @ResponseWrapper(localName = "sendOctetResponse", targetNamespace = "http://attachment.tip/", className = "tip.attachment.SendOctetResponse") public void sendOctet( @WebParam(name = "octet", targetNamespace = "") DataHandler octet);}

As mentioned earlier, JAX-WS relies on JAXB to handle the data binding for most of its Web services content. The mapping for the expectedContentTypes element is defined in Appendix H of the JAXB 2.0

Page 73: Jax Rpc Versus Jax Ws

specification (see Resources). The JAXB 2.0 mappings are similar to the JAX-RPC mappings. Compare these mappings in Table 1.

Table 1. MIME type to Java type mappingsMIME type JAX-RPC mapping JAX-WS/JAXB mappingimage/gif java.awt.Image java.awt.Imageimage/jpg java.awt.Image java.awt.Imagetext/plain java.lang.String javax.xml.transform.Sourcetext/xml javax.xml.transform.Source javax.xml.transform.Source

application/xml javax.xml.transform.Source javax.xml.transform.Sourcemultipart/* javax.mail.internet.MimeMultipartjavax.activation.DataHandler

all other types javax.activation.DataHandler javax.activation.DataHandler

enabling/disabling attachment support

One of the of additional benefits of MTOM is the fact that you can turn it on or off. In the case of Sw/A, if one side or the other doesn't support sending Sw/A attachments, then the contract defined by the WSDL cannot be honored. On the other hand, if you have an MTOM WSDL such as that in listing 3 or 5, a client could choose to send data as an MTOM attachment or inline in the SOAP message. No matter what the client chooses, it can still interact with the Web service. MTOM is just an optimization of sending content, not a mandate like Sw/A.

Back to top

Sw/A and JAX-WS

Page 74: Jax Rpc Versus Jax Ws

JAX-WS still supports the Sw/A model. By default, JAX-WS maps a Sw/A attachment to a byte[] on the Java interface, like the sample in Listing 4. To get the mapping you are used to in JAX-RPC, you can use the enableMIMEContent WSDL binding definition (see section 8.7.5 of the JAX-WS specification for more details). Listing 7 shows the JAX-WS version of the Java interface equivalent to the JAX-RPC version of the interface in listing 2.

Listing 7. JAX-WS Java interface with Sw/A attachments mapped from the mime:contentpackage tip.attachment;

import java.awt.Image;import javax.activation.DataHandler;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebService;import javax.jws.soap.SOAPBinding;

@WebService(name = "AttachmentTip", targetNamespace = "http://attachment.tip/")@SOAPBinding(style = SOAPBinding.Style.RPC)public interface AttachmentTip {

@WebMethod public void sendImage( @WebParam(name = "image", partName = "image") Image image);

@WebMethod public void sendOctet(

Page 75: Jax Rpc Versus Jax Ws

@WebParam(name = "octet", partName = "octet") DataHandler octet);

}

Back to top

Summary

JAX-RPC supports the Sw/A model. JAX-WS supports Sw/A as well, but it has also stepped up to the new MTOM model. MTOM is an improvement upon Sw/A in a number of ways:

Everything necessary to create a Java interface is now available in the WSDL interface.

MTOM is usable in a document/literal wrapped WSDL.

MTOM allows optimization to attachments, but it doesn't force attachments like Sw/A does.