JAX-RPC Client Environment:
Service endpoint can be implemented using any platform or language.
May generate client code from WSDL:
Static stub (compile time)
Dynamic proxy (runtime)
May call Web Service directly:
Dynamic invocation interface (DII)
Can use either J2SE or J2EE programming model.
There are three Web Service Client programming models:
Stub-based (least dynamic)
Both interface (WSDL) and implementation (stub) created at compile time.
Dynamic proxy
Interface (WSDL) created at compile time. Implementation (dynamic proxy) created at runtime.
Dynamic invocation interface (DII)
Both interface (WSDL) and implementation created at runtime.
Stub-based Invocation Model
Stub class gets generated at compile time
Instantiated using vendor-generated Service implementation class
Best performance
Stub class implements javax.xml.rpc.Stub interface and Web Service definition interface (com.example.HelloIF)
package javax.xml.rpc;
import java.util.Iterator;
public interface Stub {
/**
* Standard property: User name for authentication.
*/
public static final String USERNAME_PROPERTY = Call.USERNAME_PROPERTY;
/**
* Standard property: Password for authentication.
*/
public static final String PASSWORD_PROPERTY = Call.PASSWORD_PROPERTY;
/**
* Standard property: Target service endpoint address. The
* URI scheme for the endpoint address specification must
* correspond to the protocol/transport binding for this
* stub class.
*/
public static final String ENDPOINT_ADDRESS_PROPERTY = "javax.xml.rpc.service.endpoint.address";
/**
* Standard property: This boolean property is used by a service
* client to indicate whether or not it wants to participate in
* a session with a service endpoint. If this property is set to
* true, the service client indicates that it wants the session
* to be maintained. If set to false, the session is not maintained.
* The default value for this property is false.
*/
public static final String SESSION_MAINTAIN_PROPERTY = Call.SESSION_MAINTAIN_PROPERTY;
public void _setProperty(String name, Object value);
public Object _getProperty(String name);
public Iterator _getPropertyNames();
}

Steps for Stub-Based Invocation Client:
Generate Stubs
Create Client code
Compile the Client code with remote interface and stubs in CLASSPATH
Run the Client with JAX-RPC generated code and runtime
Stand-alone Stub-based Client example:
package com.example;
import javax.xml.rpc.Stub;
public class HelloClient {
public static void main(String[] args) {
try {
Stub stub = (Stub) (new MyHelloService_Impl().getHelloIFPort());
stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, args[0]);
HelloIF hello = (HelloIF) stub;
println(hello.sayHello("Duke!"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
J2EE Stub-based Client example:
package com.example;
import javax.xml.rpc.Stub;
public class HelloClient {
public void callSayHello {
try {
Context ic = new InitialContext();
Service service = (Service) ic.lookup("java:comp/env/service/HelloService");
HelloIF hello = (HelloIF) service.getHelloServiceProviderPort();
println(hello.sayHello("Duke!"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Dynamic Proxy-based Invocation Model
At Runtime Application provides the WSDL
Dynamic proxy is generated on the fly by JAX-RPC runtime system
Slower than stub-based: proxy created and casted
More portable than stub-based: does not depend on vendor generated service class before runtime
Dynamic Proxy Client example:
package com.example;
import java.net.URL;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
public class HelloClient {
public static void main(String[] args) {
try {
String UrlString = "http://localhost:8080/ProxyHelloWorld.wsdl";
String nameSpaceUri = "http://sample.proxy.org/wsdl";
String serviceName = "HelloWorld"; // maps to service name in WSDL
String portName = "HelloIFPort"; // maps to port name in WSDL
URL helloWsdlUrl = new URL(UrlString);
ServiceFactory serviceFactory = ServiceFactory.newInstance();
// Create a Service object named helloService
Service helloService = serviceFactory.createService(helloWsdlUrl, new QName(nameSpaceUri, serviceName));
// Destination for service endpoint retrieval
QName qn = new QName(nameSpaceUri, portName);
// Create a proxy with type of interface 'com.example.HelloIF'
HelloIF myProxy = (HelloIF) helloService.getPort(qn, com.example.HelloIF.class);
System.out.println(myProxy.sayHello("Duke"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
WSDL:
... <service name="HelloWorld"> <port name="HelloIFPort" binding="tns:HelloWorldBinding"> <soap:address location="http://example.com/HelloWorld"/> </port> </service> ...
The javax.xml.rpc.Service interface :
package javax.xml.rpc;
import javax.xml.namespace.QName;
import javax.xml.rpc.encoding.TypeMappingRegistry;
import javax.xml.rpc.handler.HandlerRegistry;
public interface Service {
/**
* The getPort method returns either an instance of a generated
* stub implementation class or a dynamic proxy. A service client
* uses this dynamic proxy to invoke operations on the target
* service endpoint. The <code>serviceEndpointInterface</code>
* specifies the service endpoint interface that is supported by
* the created dynamic proxy or stub instance.
*/
public java.rmi.Remote getPort(QName portName, Class serviceEndpointInterface)
throws ServiceException;
/**
* The getPort method returns either an instance of a generated
* stub implementation class or a dynamic proxy. The parameter
* <code>serviceEndpointInterface</code> specifies the service
* endpoint interface that is supported by the returned stub or
* proxy. In the implementation of this method, the JAX-RPC
* runtime system takes the responsibility of selecting a protocol
* binding (and a port) and configuring the stub accordingly.
* The returned <code>Stub</code> instance should not be
* reconfigured by the client.
*/
public java.rmi.Remote getPort(Class serviceEndpointInterface)
throws ServiceException;
public Call[] getCalls(QName portName) throws ServiceException;
public Call createCall(QName portName) throws ServiceException;
public Call createCall(QName portName, QName operationName)
throws ServiceException;
public Call createCall(QName portName, String operationName)
throws ServiceException;
public Call createCall() throws ServiceException;
public QName getServiceName();
public java.util.Iterator getPorts() throws ServiceException;
public java.net.URL getWSDLDocumentLocation();
public TypeMappingRegistry getTypeMappingRegistry();
public HandlerRegistry getHandlerRegistry();
}
Dynamic Invocation Interface (DII) Model
Gives complete control to client programmer
Most dynamic but complex programming
Create JAX-RPC javax.xml.rpc.Call object first, set operation and parameters during runtime
Could combine with UDDI lookup and WSDL parsing for dynamic lookup and discovery
Used when service definition interface is NOT known until runtime
Dynamic Invocation Interface (DII) Client example:
package com.example;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.ParameterMode;
public class HelloClient {
private static String endpoint = "http://localhost:8080/dynamic-jaxrpc/dynamic";
private static String qnameService = "Hello";
private static String qnamePort = "HelloIF";
private static String BODY_NAMESPACE_VALUE = "http://dynamic.org/wsdl";
private static String ENCODING_STYLE_PROPERTY = "javax.xml.rpc.encodingstyle.namespace.uri";
private static String NS_XSD = "http://www.w3.org/2001/XMLSchema";
private static String URI_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
public static void main(String[] args) {
try {
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(new QName(qnameService));
QName port = new QName(qnamePort);
//create JAX-RPC Call using JAX-RPC Service's createCall() method.
Call call = service.createCall(port);
// Configure your Call instance with its setter methods
call.setTargetEndpointAddress(endpoint);
call.setProperty(Call.SOAPACTION_USE_PROPERTY, new Boolean(true));
call.setProperty(Call.SOAPACTION_URI_PROPERTY, "");
call.setProperty(ENCODING_STYLE_PROPERTY, URI_ENCODING);
QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
call.setReturnType(QNAME_TYPE_STRING);
call.setOperationName(new QName(BODY_NAMESPACE_VALUE "sayHello"));
call.addParameter("String_1", QNAME_TYPE_STRING, ParameterMode.IN);
String[] params = { "Duke!" };
// Invoke the WS operation using the JAX-RPC Call's invoke method
String result = (String) call.invoke(params);
System.out.println(result);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
The javax.xml.rpc.Call interface:
package javax.xml.rpc;
import javax.xml.namespace.QName;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* The <code>javax.xml.rpc.Call</code> interface provides support
* for the dynamic invocation of a service endpoint. The
* <code>javax.xml.rpc.Service</code> interface acts as a factory
* for the creation of <code>Call</code> instances.
*/
public interface Call {
/**
* Standard property: User name for authentication
*/
public static final String USERNAME_PROPERTY = "javax.xml.rpc.security.auth.username";
/**
* Standard property: Password for authentication
*/
public static final String PASSWORD_PROPERTY = "javax.xml.rpc.security.auth.password";
/**
* Standard property for operation style. This property is
* set to "rpc" if the operation style is rpc; "document"
* if the operation style is document.
*/
public static final String OPERATION_STYLE_PROPERTY = "javax.xml.rpc.soap.operation.style";
/**
* Standard property for SOAPAction. This boolean property
* indicates whether or not SOAPAction is to be used. The
* default value of this property is false indicating that
* the SOAPAction is not used.
*/
public static final String SOAPACTION_USE_PROPERTY = "javax.xml.rpc.soap.http.soapaction.use";
/**
* Standard property for SOAPAction. Indicates the SOAPAction
* URI if the <code>javax.xml.rpc.soap.http.soapaction.use</code>
* property is set to <code>true</code>.
*/
public static final String SOAPACTION_URI_PROPERTY = "javax.xml.rpc.soap.http.soapaction.uri";
/**
* Standard property for encoding Style: Encoding style specified
* as a namespace URI. The default value is the SOAP 1.1 encoding
* <code>http://schemas.xmlsoap.org/soap/encoding/</code>
*/
public static final String ENCODINGSTYLE_URI_PROPERTY = "javax.xml.rpc.encodingstyle.namespace.uri";
/**
* Standard property: This boolean property is used by a service
* client to indicate whether or not it wants to participate in
* a session with a service endpoint. If this property is set to
* true, the service client indicates that it wants the session
* to be maintained. If set to false, the session is not maintained.
* The default value for this property is <code>false</code>.
*/
public static final String SESSION_MAINTAIN_PROPERTY = "javax.xml.rpc.session.maintain";
/**
* Indicates whether <code>addParameter</code> and
* <code>setReturnType</code> methods
* are to be invoked to specify the parameter and return type
* specification for a specific operation.
*/
public boolean isParameterAndReturnSpecRequired(QName operationName);
/**
* Adds a parameter type and mode for a specific operation.
* Note that the client code may not call any
* <code>addParameter</code> and <code>setReturnType</code>
* methods before calling the <code>invoke</code> method. In
* this case, the Call implementation class determines the
* parameter types by using reflection on parameters, using
* the WSDL description and configured type mapping registry.
*/
public void addParameter(String paramName, QName xmlType, ParameterMode parameterMode);
/**
* Adds a parameter type and mode for a specific operation.
* This method is used to specify the Java type for either
* OUT or INOUT parameters.
*
* @param paramName Name of the parameter
* @param xmlType XML datatype of the parameter
* @param javaType The Java class of the parameter
* @param parameterMode Mode of the parameter-whether
* ParameterMode.IN, OUT or INOUT
*/
public void addParameter(String paramName, QName xmlType, Class javaType, ParameterMode parameterMode);
/**
* Gets the XML type of a parameter by name.
*/
public QName getParameterTypeByName(String paramName);
/**
* Sets the return type for a specific operation. Invoking
* <code>setReturnType(null)</code> removes the return
* type for this Call object.
*/
public void setReturnType(QName xmlType);
/**
* Sets the return type for a specific operation.
*/
public void setReturnType(QName xmlType, Class javaType);
/**
* Gets the return type for a specific operation.
*/
public QName getReturnType();
/**
* Removes all specified parameters from this <code>Call</code> instance.
* Note that this method removes only the parameters and not
* the return type. The <code>setReturnType(null)</code> is
* used to remove the return type.
*/
public void removeAllParameters();
/**
* Gets the name of the operation to be invoked using this Call instance.
*/
public QName getOperationName();
/**
* Sets the name of the operation to be invoked using this
* <code>Call</code> instance.
*/
public void setOperationName(QName operationName);
/**
* Gets the qualified name of the port type.
*/
public QName getPortTypeName();
/**
* Sets the qualified name of the port type.
*/
public void setPortTypeName(QName portType);
/**
* Sets the address of the target service endpoint.
* This address must correspond to the transport specified
* in the binding for this <code>Call</code> instance.
*/
public void setTargetEndpointAddress(String address);
/**
* Gets the address of a target service endpoint.
*/
public String getTargetEndpointAddress();
/**
* Sets the value for a named property. JAX-RPC specification
* specifies a standard set of properties that may be passed
* to the <code>Call.setProperty</code> method.
*/
public void setProperty(String name, Object value);
/**
* Gets the value of a named property.
*/
public Object getProperty(String name);
/**
* Removes a named property.
*/
public void removeProperty(String name);
/**
* Gets the names of configurable properties supported by
* this <code>Call</code> object.
*/
public Iterator getPropertyNames();
// Remote Method Invocation methods
/**
* Invokes a specific operation using a synchronous request-response
* interaction mode.
*/
public Object invoke(Object[] inputParams) throws java.rmi.RemoteException;
/**
* Invokes a specific operation using a synchronous request-response
* interaction mode.
*/
public Object invoke(QName operationName, Object[] inputParams)
throws java.rmi.RemoteException;
/**
* Invokes a remote method using the one-way interaction mode. The
* client thread does not block waiting for the completion of the
* server processing for this remote method invocation. This method
* must not throw any remote exceptions. This method may throw a
* <code>JAXRPCException</code> during the processing of the one-way
* remote call.
*/
public void invokeOneWay(Object[] params);
/**
* Returns a <code>Map</code> of {name, value} for the output parameters of
* the last invoked operation. The parameter names in the
* returned Map are of type <code>java.lang.String</code>.
*/
public Map getOutputParams();
/**
* Returns a <code>List</code> values for the output parameters
* of the last invoked operation.
*/
public List getOutputValues();
}
Table 4.1. Usage scenarios of the three Web Service service client styles.
| Static stub | Dynamic proxy | Dynamic Invocation Interface (DII) |
|---|---|---|
| Web service not expected to change | Some changes to the Web Service expected, such as the location of the service |
Considerable changes to the Web service expected, such as:
|
| Most common scenario | Less common | Less common |
| You can generate a stub class either from WSDL (using WSDL2Java) or from a service endpoint interface. A generated stub class is required to implement both javax.xml.rpc.Stub and the service endpoint interface. This stub interface provides APIs to configure stubs by setting properties like endpoint address, session, user name, password, etc. | The client at runtime creates dynamic proxy stubs using the javax.xml.rpc.Service interface. The client has a priori knowledge of the WSDL and the service it is going to invoke. It uses the javax.xml.rpc.ServiceFactory classes to create the service and get the proxy. | This software pattern eliminates the need for clients to know in advance a service's exact name and parameters. A DII client can discover this information at runtime using a service broker that can look up the service's information. This flexibility in service discovery enables the run-time system to use service brokers, which can adopt varying service discovery mechanisms - ebXML registries, UDDI, etc. |
|
|
Hosting provided by PerfoHost: KVM VPS. Unix VPS. Windows VPS. VPN. Domains. Dedicated servers. Colocation.