![]() | |
|
Empty
Class
A Java class (not an interface) annotated with a javax.jws.WebService annotation can be used to define a Web service.
In order to allow for a separation between Web service interface and implementation, if the WebService annotation on the class under consideration has a endpointInterface element, then the interface referred by this element is for all purposes the SEI associated with the class.
Otherwise, the class implicitly defines a service endpoint interface (SEI) which comprises all of the public methods that satisfy one of the following conditions:
They are annotated with the javax.jws.WebMethod annotation with the exclude element set to false or missing (since false is the default for this annotation element).
They are NOT annotated with the javax.jws.WebMethod annotation but their declaring class has a javax.jws.WebService annotation.
For mapping purposes, this implicit SEI and its methods are considered to be annotated with the same Web service-related annotations that the original class and its methods have.
In pratice, in order to exclude a public method of a class annotated with WebService and not directly specifying a endpointInterface from the implicitly defined SEI, it is necessary to annotate the method with a WebMethod annotation with the exclude element set to true.
For mapping purposes, this class must be a top level class or a static inner class. As defined by JSR 181, a class annotated with javax.jws.WebService MUST HAVE a default public constructor.
Interface
A Java service endpoint interface (SEI) is mapped to a wsdl:portType element. The wsdl:portType element acts as a container for other WSDL elements that together form the WSDL description of the methods in the corresponding Java SEI. An SEI is a Java interface that meets all of the following criteria:
It MUST carry a javax.jws.WebService annotation
Any of its methods MAY carry a javax.jws.WebMethod annotation
javax.jws.WebMethod if used, MUST NOT have the exclude element set to true.
All method parameters and return types are compatible with the JAXB 2.0 Java to XML Schema mapping definition
Method
Each public method in a Java SEI is mapped to a wsdl:operation element in the corresponding wsdl:portType plus one or more wsdl:message elements.
Comparing JAX-WS and JAX-RPC SEI mapping
WSDL for a simple HelloWorld Web service:
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:tns="urn:helloWorld/sample/ibm/com" ...> <wsdl:types> <xsd:schema ...> <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" 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"> <wsdl:port name="port" binding="tns:HelloWorldBinding"> <soap:address location="http://server.org/" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
JAX-RPC HelloWorld SEI:
package com.ibm.samples; public interface HelloWorld extends java.rmi.Remote { ... }
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 { ... }
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. 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.
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.
Comparing JAX-WS and JAX-RPC operation mapping
Exploring the document/literal wrapped pattern
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; }
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 = "") String name ); }
As you can see, the JAX-WS mapping again has a lot of annotations. Another 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 pattern
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.
Document/literal WSDL:
<wsdl:types> <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com" xmlns:tns="urn:helloWorld/sample/ibm/com" ... > <xsd:element name="hello" type="xsd:string"/> <xsd:element name="helloResponse" 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>
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.
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; }
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.
Exploring the RPC/literal patterns
With an RPC/literal style WSDL, the parts are defined in terms of types rather than elements. Listing below contains the relevant WSDL differences.
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>
JAX-RPC RPC/literal mapping:
public interface HelloWorld extends java.rmi.Remote { public java.lang.String hello(java.lang.String helloParameters) throws java.rmi.RemoteException; }
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 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 JAX-WS and JAX-RPC 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.
JAX-WS asynchronous callback:
@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 Future<?> helloAsync( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "asyncHandler", targetNamespace = "") AsyncHandler<String> asyncHandler );
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", 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 for JAX-WS and JAX-RPC
Both JAX-RPC and JAX-WS support parameters known as IN/OUT parameters. 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.
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> <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>
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; }
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", 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.
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.
![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |