Oracle9i Application Server Oracle9iAS SOAP Developer's Guide
Release 1 (v1.0.2.2)

Part Number A90297-01
Go To Documentation Library
Library
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

6
Writing SOAP Providers

This chapter describes the Oracle SOAP Provider Interface and includes information on the following topics:

Provider Interface Overview

Oracle SOAP includes a prepackaged provider implementation. In addition, Oracle SOAP includes a Provider Interface that allows you to write a custom provider to support services of types other than the prepackaged types. You can add a provider to support a service by implementing the Provider Interface.

Oracle SOAP includes provider implementations to support services for the following:

Implementing a Provider Interface

The Oracle SOAP Provider Interface is a Java interface that enables the SOAP Request Handler Servlet to work uniformly with different types of service providers. A SOAP Provider, also called a service provider, is an implementation of the Provider Interface that encapsulates the logic necessary to invoke methods on a specific type of service. Using a provider that is an implementation of the Provider Interface simplifies the SOAP Request Handler Servlet and allows you to add new types of service providers.


Note:

When adding a new provider type, you only need to implement the Provider Interface once for each type of service. Thus, a SOAP server supports a small number of types of service providers and a potentially large number of services. 


This section shows the basic steps for building a custom provider. For specific details, and a sample of the code required to build a custom provider, see the provider sample supplied with Oracle SOAP in the directory $SOAP_HOME/samples/provider.

Developing a custom SOAP Provider consists of the following steps:

Implementing Provider Interface Methods

The provider writer implements the following methods that are included in the Provider Interface:

public void destroy();
public String getId();
public void init(ProviderDeploymentDescriptor pd, SOAPServerContext ssc);
public void invoke(RequestContext requestContext);

Working with the Provider init() Method

The init() method receives the provider configuration deployment descriptor options and initializes the provider using the supplied configuration information. Provider-specific options are passed to the init() method as attributes from the SOAP Request Handler Servlet. Use these attributes to initialize an instance of the provider. An example of provider-specific options are the Hostname and Port for a Database Server Connection.

The provider init() method handles any required initialization that is required as a one-time-only initialization for service providers. The init() method is invoked by the SOAP Request Handler Servlet exactly once before the handler makes any requests to services that the provider supports. This process allows the provider to set up any required provider-specific global context.

Working with the Provider invoke() Method

After provider initialization occurs, most of the work for the provider implementation occurs in the invoke() method. This method invokes the requested method in the specified SOAP service.

The invoke() method performs the following important actions:

The SOAP Request Handler Servlet passes service-specific options to the provider. These options are read from the service deployment descriptor when the service is deployed. Service-specific options describe a service deployed in a provider. An example of a service-specific option is the name of the Java class for a method that implements a Java service.

The invoke() parameter of type RequestContext completely describes a service request. Given the RequestContext, the invoke() method takes care of certain steps, as shown in the following procedure. For complete details on the code for these steps, see the provider sample supplied with Oracle SOAP in the directory $SOAP_HOME/samples/provider.

  1. Get the service-specific options, and build the SOAPMappingRegistry. Use the RequestContext method getServiceDeploymentDescriptor() to get the service options.

    UserContext ucontext = rc.getUserContext();
    String      serviceId = rc.getServiceId();
    ServiceDeploymentDescriptor sd = rc.getServiceDeploymentDescriptor();
    SOAPMappingRegistry smr =
                    ServiceDeploymentDescriptor.buildSOAPMappingRegistry(sd);
    
    
    
  2. Unmarshall the parameters for the service method using a Call object, Call.extractFromEnvelope(), and the RequestContext method getRequestEnvelope().

    Call call = Call.extractFromEnvelope(rc.getRequestEnvelope(), smr);
    rc.setRequestEncodingStyle(call.getEncodingStyleURI());
    
    
  3. Build the arguments and determine response encoding style using call.getEncodingStyleURI() and param.getEncodingStyleURI().

    String respEncStyle = call.getEncodingStyleURI();
    Vector params = call.getParams ();
    Object[] args = null;
    Class[] argTypes = null;
    if (params != null)
    {
       int paramsCount = params.size ();
       args = new Object[paramsCount];
       argTypes = new Class[paramsCount];
       for (int i = 0; i < paramsCount; i++)
       {
          Parameter param = (Parameter) params.elementAt (i);
          args[i] = param.getValue ();
          argTypes[i] = param.getType ();
          if (respEncStyle == null)
          {
             respEncStyle = param.getEncodingStyleURI ();
      }
     }
     }
    
  4. Set a default encoding for the response.

    if (respEncStyle == null)
    {            
       respEncStyle = Constants.NS_URI_SOAP_ENC;
    }
    rc.setRequestEncodingStyle(respEncStyle);
    
    
  5. Invoke the service method, and obtain a result and a vector of parameters for any parameters that are returned (outParams).

    Bean        result = null;
    Vector      outParams = new Vector();
    try
    {
       m_log.log("Invoking method '" + methodName + "'", Logger.SEVERITY_DEBUG);
       result = new Bean(String.class, "this is the result");
       outParams.addElement(
                    new Parameter("paramName", String.class, "this is a param",
                        null));
    }
    catch (Throwable t)
    {
       throw new SOAPException(Constants.FAULT_CODE_SERVER,
    }
    
    
  6. Create a response, and save the result as a Response object. The SOAP Request Handler Servlet marshals the envelope before returning.

    try
    {
        if (sd.getServiceType() ==
                ServiceDeploymentDescriptor.SERVICE_TYPE_RPC)
        {
             Parameter ret = null;
            if (result != null && result.type != void.class)
            {
                ret = new Parameter (RPCConstants.ELEM_RETURN,
                    result.type, result.value, null);
            }
            Response resp = new Response(rc.getServiceId(),
                call.getMethodName(), ret, outParams, null, respEncStyle);
    
             try
            {
                Envelope respEnvelope = resp.buildEnvelope();
                rc.setResponseEnvelope(respEnvelope);
                rc.setResponseMap(smr);
            }
            catch (Exception e)
            {
                throw new SOAPException (Constants.FAULT_CODE_SERVER,
                    "error building response envelope", e);
            }
    
        }
        else
        {
            throw new SOAPException (Constants.FAULT_CODE_SERVER,
                "invalid service type");
          }
    
    }
    catch (Exception e)
    {
        m_log.log("Error creating response: " + e, Logger.SEVERITY_DEBUG);
        throw new SOAPException (Constants.FAULT_CODE_SERVER,
            "error creating response", e);
    }
    
    

Working with the Provider destroy() Method

The destroy() method performs one-time service provider cleanup. This method is invoked by the SOAP Request Handler Servlet exactly once before the handler shuts down. This method gives the provider the opportunity to do global cleanup, such as closing connections.

Working with the Provider getId() Method

The getId() method supplies the provider ID. The provider ID, for a particular provider is unique within the SOAP Request Handler Servlet.

Handling Provider Deployment

After implementing a custom provider, if you are using the default Provider Manager and the default Service Manager, you should update the XML provider deployment descriptor schema and the XML service deployment descriptor schema to conform to the new requirements for the new provider. This sections covers the following:

Updating the Provider Deployment Descriptor Schema

A service provider must be deployed to make its services available. To deploy a service provider, you can either implement a custom Provider Manager or use the default Provider Manager and deploy providers using the Provider Manager Client. The default Provider Manager reads an XML provider deployment descriptor that conforms to the XML provider deployment schema.

Example 6-1 shows a sample provider deployment descriptor file for a SOAP service using a custom Provider.

Example 6-1 Custom Provider Deployment Descriptor

<isd:provider xmlns:isd="http://xmlns.oracle.com/soap/2001/04/deploy/provider"
    id="company-provider"
    class="oracle.soap.providers.sp.SpProvider" >
  <isd:storedProcedure jdbc="jdbc:oracle:oci8"
           username="scott"
           password="tiger"
           service="YOUR-SERVICE-NAME" />
</isd:provider>

See Also:

$SOAP_HOME/schema/provider.xsd for the complete provider deployment descriptor schema 

Updating the Service Deployment Descriptor Schema

A service provider encapsulates all of the logic necessary to invoke SOAP methods in services that are implemented as a specific type, such as a stored procedure or a Java class. A service provider must be deployed to make its services available. To deploy a service provider, implement a custom Service Manager, or use the default Service Manager and deploy providers with the Service Manager Client.

The default Server Manager reads an XML service deployment descriptor that conforms to the XML schema.

Example 6-2 shows a custom Service Deployment Descriptor file for a SOAP service using a custom Provider.

Example 6-2 Custom Service Deployment Descriptor

 <isd:service xmlns:isd="http://xmlns.oracle.com/soap/2001/04/deploy/service"
    id="urn:www-oracle-com:company"
    type="rpc" >
   <isd:provider
        id="company-provider"
        methods="ADDEMP GETEMP GETADDRESS GETEMPINFO CHANGESALARY REMOVEEMP"
        scope="Application" >

       <isd:storedProcedure schema="SCOTT" package="COMPANY" />

   </isd:provider>

  <isd:mappings>
    <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
             xmlns:x="urn:company-sample" qname="x:EMPLOYEE"
             javaType="samples.sp.company.Employee"
             sqlType="SCOTT.EMPLOYEE"
             java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
             
xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
    <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
             xmlns:x="urn:company-sample" qname="x:ADDRESS"
             javaType="samples.sp.company.Address"
             sqlType="SCOTT.ADDRESS"
             java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
             
xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
  </isd:mappings>

  <isd:faultListener class="org.apache.soap.server.DOMFaultListener"/>

</isd:service>


See Also:

$SOAP_HOME/schema/service.xsd for the complete service deployment descriptor schema. 



Go to previous page Go to next page
Oracle
Copyright © 2001 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Library
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index