SCDJWS Study Guide: JAX-RPC
There are two families of clients, which differ in the way the code is written, packaged, and invoked:
- Unmanaged clients
- J2EE container-managed clients.
Here, unmanaged means not J2EE container-managed. These are Java 2 Standard Edition (J2SE) clients and are invoked with a simple java command.
For unmanaged clients, the service lookup is through the JAX-RPC ServiceFactory, a factory for the creation of instances of services access points. For J2EE container-managed clients, service lookup is through JNDI lookup.
The JAX-RPC ServiceFactory is the standard way to look up Web services in a J2SE environment. The JAX-RPC ServiceFactory is an abstract class which acts as a factory for instantiating JAX-RPC Services. It is vendor independent and lets you write portable code. The ServiceFactory is instantiated and used as follows: javax.xml.rpc.Service service = ServiceFactory.newInstance().createService(...);
You need to pass the fully qualified name of the Web service, that is namespace plus service name, to the createService() method and optionally the URL of the WSDL document describing the Web service you want to look up. The steps are as follows:
- Optionally, specify the WSDL URL.
- Specify the Web service's fully qualified name.
- Invoke ServiceFactory's createService() method.
The Service Interface obtained is then used to get a stub, dynamic proxy, or DII Call object, as described in the JAX-RPC client-side programming model section. Also covered in that section is the Dynamic Invocation Interface (DII). With this method, you do not need to know the WSDL URL of the Web service you want to invoke, and you only specify the service name parameter to the createService() method. The following code portion shows how to use the JAX-RPC ServiceFactory to instantiate a JAX-RPC Service. QName is a javax.xml.namespace.QName.
wsdlURL = http://localhost:6080/HelloWebService/services/Hello?wsdl";
String namespace = "http://Hello.com";
String serviceName = "HelloWebService";
QName serviceQN = new QName(namespace, serviceName);
ServiceFactory serviceFactory = ServiceFactory.newInstance();
/* The "new URL(wsdlURL)" parameter is optional */
Service service = serviceFactory.createService(new URL(wsdlURL), serviceQN);
There are vendor-specific alternatives to the JAX-RPC ServiceFactory. These are usually very easy to use (the client code is very simple to write) if you want to use a vendor's stub. However, such extensions are not standard and will probably not work on other vendor's J2EE implementations.
JNDI Service Lookup
container-managed clients are packaged into Enterprise Archives (.EAR)
run from inside a J2EE container. In addition to the Java code,
also packaged into the archive. Several different types of J2EE
container-managed clients are:
- Application client container clients
- Web container clients: JavaBean or Servlet
- EJB container clients: EJB
JAX-RPC defines the programming model for unmanaged clients, whereas JSR 109, "Implementing Enterprise Web services", defines the programming model for J2EE container-managed clients. One of the goals of JSR 109 is that its client programming model is compatible with JAX-RPC. However, JSR 109 does not recommend the use of the JAX-RPC ServiceFactory. It recommends clients use Java Naming and Directory Interface (JNDI) instead to obtain a Service Interface. This is a two step process:
- Instantiate a local JNDI Context.
- Do a JNDI lookup for the Web service name in this context.
Context ic = new
Service service = (Service) ctx.lookup("java:comp/env/service/HelloService");
The name of the Web service, in this case java:comp/env/service/HelloService, is specified in the client application's deployment descriptor. JSR 109 recommends that all service reference logical names be organized under the service sub-context. With the client environment context being java:comp/env, you end up with:
name in context = client environment
context + "service" subcontext + service name.
In this case, the service name in context is: java:comp/env/ + service/ + HelloService.
service subcontext + service
example, service/HelloService) is
also called the logical service name and is declared in the Web service
application's deployment descriptor.
The JNDI lookup returns a JAX-RPC Service Interface. The J2EE container makes sure an implementation of the generic JAX-RPC Service is bound at the location specified in the deployment descriptor. You can also cast the object returned by the lookup to the specific interface for your Web service. This is shown on the following code, where the HelloService extends the generic JAX-RPC Service interface.
Context ic= new
HelloServiceInterface service =
Service Interface obtained is then used
to get a static stub, dynamic proxy, or a DII Call object.