Skip Headers
Oracle® Application Server Advanced Web Services Developer's Guide
10g (10.1.3.1.0)

Part Number B28975-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

9 Using Web Services Invocation Framework

This chapter describes Oracle Application Server Web Services support for the Web Services Invocation Framework (WSIF).

This chapter contains the following sections.

Understanding WSIF

WSIF provides a standard API for working with representations of different Web service messaging protocols as an alternative to working directly with a JAX-RPC SOAP client API. The WSIF API allows the client to use native protocols to communicate with the service.

The WSIF API allows a Web service to communicate with Web service components, such as Java classes, EJBs, or database resources, through a single interface. In addition to JAX-RPC which understands only SOAP, WSIF clients can directly use other protocols, such as RMI, IIOP, or JDBC.

To support different messaging protocols, you can add different WSIF bindings to the WSDL. This is in contrast to the SOAP protocol, where you add a SOAP binding. WSIF and SOAP bindings can co-exist in the same WSDL. This enables you to define both native and SOAP bindings for a particular service. For example, you can expose an EJB with a WSIF port and a SOAP port. Clients can access the same Web service even though they may be using different protocols. The protocol that is used to communicate with the service is determined by selecting a particular binding in the client: either a SOAP or a WSIF binding.

Note:

WSIF invocations will map the primitive and nillable XML schema types to primitive Java types. This does not permit the representation of XML nil values.

As a work around, use SOAP-encoded XML types in the WSDL.

WSIF is sponsored by the Apache Software Group. For more information on WSIF, see the following Web site.

http://ws.apache.org/wsif/

Understanding WSIF Architecture

In the WSIF architecture, communications between the client and Web services are enabled through the WSDL. The WSDL becomes the normalized description of the software interface.

Figure 9-1 illustrates the WSIF architecture for OracleAS Web Services. The following steps describe the data flow through the architecture.

  1. Program the WSIF client according to the content of the abstract service description portion of the WSDL. This portion of the WSDL includes port types, operations, and message exchanges.

  2. At runtime, the WSIF client selects a concrete binding in the WSDL that determines which provider the WSIF runtime will use. Providers are protocol-specific pieces of code that provide implementation of the different WSIF bindings in the WSDL.

  3. The WSIF client makes calls into the WSIF API to invoke the Web service. This API is based on the abstract service description portion of the WSDL. By invoking the service based on its abstract description, you can work with a service regardless of how it was implemented, its protocol, or where it resides.

  4. The WSIF runtime in the kernal determines which provider to use, based on the binding selected in Step 2.

  5. The provider interacts with the Web service.

Services can be invoked dynamically and without the need for generating stubs.

Figure 9-1 WSIF Architecture for OracleAS Web Services

Description of Figure 9-1 follows
Description of "Figure 9-1 WSIF Architecture for OracleAS Web Services"

WSIF supports providers for clients of Web services that expose JAX-RPC (SOAP), Java classes, EJBs, and database resources. You can also define your own providers. Defining your own providers is beyond the scope of this manual. For information on this topic, see the Apache Software Group Web page for WSIF.

http://ws.apache.org/wsif/

The following sections describe the WebServicesAssembler commands and Ant tasks that insert WSIF information into the WSDL.

WSIF and Java Classes

This section has the following subsections:

Providing WSIF Functionality for Java Classes

To insert WSIF Java extensions into the WSDL, OracleAS Web Services provides two arguments that can be used with the assemble or genWsdl WebServicesAssembler commands.

  • wsifJavaBinding

  • wsifJavaPort

If you assemble a Web service based on a Java class with the assemble or genWsdl commands, the wsifJavaBinding and wsifJavaPort arguments allow you to request a WSIF binding. These arguments add the appropriate WSDL extensions in the form of a WSIF binding that allow a WSIF client to access a Java class exposed as a Web service.

To configure the WSIF Java bindings for a single port, you can use either the wsifJavaBinding or wsifJavaPort argument. The wsifJavaBinding argument allows you to have a WSIF port and no additional SOAP ports in your WSDL. The wsifJavaPort argument enables you to specify multiple ports of different types within an Ant task.

While the wsifJavaBinding argument can be used either on the command line or in an Ant task, the wsifJavaPort can be used only in an Ant task.

See Also:

How to Configure WSIF Endpoints for Java Ports

WSIF endpoints for Java ports can be configured with wsifJavaBinding or wsifJavaPort.

How to Configure a Single Java Port with wsifJavaBinding

The wsifJavaBinding argument is a flag that can be used by either the assemble or genWsdl command to specify the WSIF Java binding for a single port.

If you use the wsifJavaBinding argument, then you must also provide a value for the className argument. The className argument provides the value of the java:address element in the WSDL's <port> element.

Example 9-1 illustrates a WebServicesAssembler command line for genWsdl that calls wsifJavaBinding and Example 9-2 illustrates the corresponding Ant task. The argument populates the java:address element in the WSDL's <port> element with classname="oracle.demo.hello.HelloImpl". The variable ${wsdemo.common.class.path} represents the classpath.

Example 9-1 Command Line, Using wsifJavaBinding to Configure a Single Java Port

java -jar wsa.jar -genWsdl 
                  -output wsdl 
                  -style rpc 
                  -use literal 
                  -wsifJavaBinding true 
                  -interfaceName oracle.demo.hello.HelloInterface 
                  -className oracle.demo.hello.HelloImpl 
                  -classpath ${wsdemo.common.class.path}:build/classes 

Example 9-2 Ant Task, Using wsifJavaBinding to Configure a Single Java Port

<oracle:genWsdl
    output="wsdl"
    style="rpc"
    use="literal"
    wsifJavaBinding="true"
    >
    <oracle:porttype
         interfaceName="oracle.demo.hello.HelloInterface"
         className="oracle.demo.hello.HelloImpl" 
    </oracle:porttype>
    <oracle:classpath>
         <oracle:pathelement path="${wsdemo.common.class.path}"/>
         <oracle:pathelement location="build/classes"/>
    </oracle:classpath>
</oracle:genWsdl>

In these command line and Ant task examples:

  • genWsdl—Generates a WSDL and a JAX-RPC mapping file for assembling Web services bottom up from a Java interface.

  • output—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created.

  • style—For bottom up Web service assembly, this argument specifies the style attribute of the message format in the generated WSDL.

  • use—For bottom up Web service assembly, this argument specifies the use attribute of the message format in the generated WSDL.

  • wsifJavaBinding—Used in bottom up Web services assembly to add WSIF Java bindings to the WSDL. If true, you must also specify the className of the Java implementation class. WebServicesAssembler will generate native WSIF Java bindings in addition to SOAP bindings in the WSDL.

  • interfaceName—Specifies the name of a Java class (including the package name) that contains the service endpoint interface (SEI).

  • className—Specifies the name of the class (including the package name) that is the implementation class for the Web service.

  • classpath—Specifies the classpath that contains any user-created classes given to WebServicesAssembler. One reason to specify this argument is if you have already created some value type classes or exceptions and you do not want WebServicesAssembler to overwrite them.

See Also:

"Using WebServicesAssembler", in the Oracle Application Server Web Services Developer's Guide for more detailed information on these arguments.

How to Configure a Single Java Port with wsifJavaPort

The wsifJavaPort argument can be used only in an Ant task. Although you typically use wsifJavaPort to specify WSIF Java bindings for multiple ports, you can also use it to specify a single port. The argument also has attributes that allow you to specify a WSIF port name, a Java class name for each port, and a custom class loader and its classpath. These attributes are passed to the java:address element in the WSDL's <port> element.

Table 9-1 describes the attributes that can be used by the wsifJavaPort argument. All of the attributes are optional.

Table 9-1 Attributes for the wsifJavaPort Argument

Attribute Description

classLoader

Specifies the name of the Java class loader. If you do not provide a value for this attribute, the value for the system class loader will be used.

className

Specifies the name of the implementation class. If you do not provide a value for this attribute, WebServicesAssembler will use the class name for the parent Ant task if it was specified.

classPath

Specifies the class path for the Java class loader. If you do not provide a value for this attribute, the system class path will be used.

name

Specifies the name of the WSIF port in the Web service. This name will be used to identify the WSIF port in the WSDL's port element.


The Ant task for genWsdl in Example 9-3 inserts WSIF Java binding code into the WSDL's binding, binding operation, and port clauses. The HelloImpl class used as the className attribute to the wsifJavaPort argument, contains a sayHello method that takes a greeting parameter of type String. The variable ${additional.class.path} represents the classpath.

Example 9-3 Using wsifJavaPort to Configure a Single Java Port

<oracle:genWsdl
       output="wsdl"
       style="rpc"
       use="literal"
       >
       <oracle:porttype
          interfaceName="oracle.demo.hello.HelloInterface">
           <oracle:wsifJavaPort name="HelloServiceJavaPort" 
                     className="oracle.demo.hello.HelloImpl"  />
       </oracle:porttype>
       <oracle:classpath>
           <oracle:pathelement path="${additional.class.path}" />
           <oracle:pathelement location="build/classes" />
       </oracle:classpath>
</oracle:genWsdl>

In this Ant task:

  • genWsdl—Generates a WSDL and a JAX-RPC mapping file for assembling Web services bottom up from a Java interface.

  • output—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created.

  • style—For bottom up Web service assembly, this argument specifies the style attribute of the message format in the generated WSDL.

  • use—For bottom up Web service assembly, this argument specifies the use attribute of the message format in the generated WSDL.

  • porttype—This tag enables you to configure different interfaces to a Web service.

  • interfaceName—Specifies the name of a Java class (including the package name) that contains the service endpoint interface (SEI).

  • wsifJavaPort—Allows you to specify WSIF Java bindings for multiple ports.

  • className—Specifies the name of the class (including the package name) that is the implementation class for the Web service.

  • classpath—Specifies the classpath that contains any user-created classes given to WebServicesAssembler. One reason to specify this argument is if you have already created some value type classes or exceptions and you do not want WebServicesAssembler to overwrite them.

See Also:

"Using WebServicesAssembler", in the Oracle Application Server Web Services Developer's Guide for more detailed information on these arguments.

Example 9-4 illustrates the WSIF Java binding code that the Ant task in the previous example inserts into the WSDL's binding, binding operation, and port clauses.

Example 9-4 WSDL Extensions for WSIF Java Bindings

...
<java:binding/>
     <format:typeMapping encoding="Java" style="Java">
           <format:typeMap typeName="xsd:string" formatType="java.lang.String"/>
     </format:typeMapping>
     ...
<java:operation
      methodName="sayHello"
      parameterOrder="greeting"
      methodType="instance"
      returnType="result" />
      ...
<port name="HelloServiceJavaPort" binding="tns:JavaBinding"> 
    <java:address className="oracle.demo.hello.HelloImpl" />
</port>
...

How to Configure Multiple Java Ports with wsifJavaPort

You can use the wsifJavaPort argument with the assemble and genWsdl commands to define WSIF bindings for multiple Java ports. Example 9-5 illustrates an Ant task that creates a WSIF port named HelloServiceJavaPort and a SOAP port named HelloServiceSoapPort. The SOAP port is created by adding the <oracle:port name="... "/> subtask. Note that className is declared in the parent Ant task. The variable ${additional.class.path} represents the classpath. Table 9-1 describes the attributes that can be used by wsifJavaPort.

Example 9-5 Using wsifJavaPort to Configure a WSIF Java Port and a SOAP Java Port

<oracle:genWsdl
       output="wsdl"
       style="rpc"
       use="literal"
       >
       <oracle:porttype
         interfaceName="oracle.demo.hello.HelloInterface"
         className="oracle.demo.hello.HelloImpl">
           <oracle:wsifJavaPort name="HelloServiceJavaPort" /> 
           <oracle:port name="HelloServiceSoapPort" /> 
       </oracle:porttype>
       <oracle:classpath>
           <oracle:pathelement path="${additional.class.path}" />
           <oracle:pathelement location="build/classes" />
       </oracle:classpath>
</oracle:genWsdl>

WSIF Java Extensions to the WSDL

To comply with the WSIF Framework definition, OracleAS Web Services inserts binding information into the WSDL that allows a Java class to be represented as a Web service. Example 9-6 illustrates the XML schema definitions for these extensions.

Example 9-4 illustrates how additional bindings, binding operations, and port clauses are added to the WSDL to describe a WSIF service.

Example 9-6 Schema Definitions to Support WSIF Java Bindings

...
<!-- Java binding --> 
<binding ... > 
    <java:binding/> 
    <format:typeMapping style="uri" encoding="..."/>? 
        <format:typeMap typeName="qname"|elementName="qname" 
              formatType="nmtoken"/>* 
    </format:typeMapping> 
    ...
    <operation>* 
        <java:operation 
            methodName="nmtoken" 
            parameterOrder="nmtoken"? 
            returnPart="nmtoken"?
            methodType="instance|static|constructor"? />? 
        <input name="nmtoken"? />? 
        <output name="nmtoken"? />? 
        <fault name="nmtoken"? />? 
    </operation> 
</binding> 
 ....
<service ... > 
    <port name="nmtoken" >* 
         <java:address 
             className="nmtoken" 
             classPath="nmtoken"? 
             classLoader="nmtoken"? /> 
    </port> 
</service>
...

WSIF and EJBs

This section contains the following subsections:

Providing WSIF Functionality for EJBs

To insert WSIF EJB extensions into the WSDL, the WebServicesAssembler tool provides two arguments that can be used with the ejbAssemble or genWsdl commands.

  • wsifEjbBinding

  • wsifEjbPort

As you assemble a Web service based on an EJB with the ejbAssemble command, the wsifEjbBinding or wsifEjbPort arguments allow you to request a WSIF binding.

These arguments add the appropriate WSDL extensions that allow a WSIF client to access an EJB exposed as a Web service.

To configure the WSIF EJB binding for a single port, you can use either the wsifEjbBinding or wsifEjbPort argument. To configure WSIF EJB bindings for multiple ports, you must use the wsifEjbPort argument.

While the wsifEjbBinding argument can be used either on the command line or in an Ant task, the wsifEjbPort can be used only in an Ant task.

See Also:

Providing WSIF Functionality for Version 3.0 EJBs

OracleAS Web Services enables you to assemble WSIF bindings for a version 3.0 EJB through the use of an Oracle proprietary addition to J2SE 5.0 Web Service Annotations. OracleAS Web Services defines an @WSIFEJBBinding annotation (oracle.webservices.annotations.@WSIFEJBBinding) that you can add to the interface file for an EJB. When the file is compiled, it generates an EJB WSIF binding in the WSDL, and an EJB port.

For more information on the @WSIFEJBBinding annotation and how to use it, see "Oracle Additions to the J2SE 5.0 JDK Annotations" in the Oracle Application Server Web Services Developer's Guide.

How to Configure WSIF Endpoints for EJB Ports

A WSIF endpoints for EJB ports can be configured with the wsifEjbBinding or wsifEjbPort argument.

How to Configure a Single EJB Port with wsifEjbBinding

The wsifEjbBinding argument can be used by either the ejbAssemble or genWsdl command to specify the WSIF EJB binding for a single port.

The wsifEjbBinding argument requires you to specify the name and jndiName arguments. The wsifEjbBinding argument passes these values to the ejb:address element in the WSDL's <port> element. The jndiProviderURL and initialContextFactory arguments provide the JNDI provider URL and JNDI initial context values. If you do not provide these arguments, then these values are obtained from the jndi.properties file.

See Also:

"wsifEjbBinding" in the Oracle Application Server Web Services Developer's Guide for more information on this argument.

Example 9-7 illustrates a WebServicesAssembler command line for genWsdl that calls wsifEjbBinding. Example 9-8 illustrates the corresponding Ant task. The argument causes the ejb:address element in the WSDL's <port> element to be populated with className="oracle.demo.hello.HelloImpl" and jndiName="HelloService2EJB". The variable ${additional.class.path} represents the classpath.

Example 9-7 Command Line, Using wsifEjbBinding to Configure a Single EJB Port

java -jar wsa.jar -genWsdl 
                  -output wsdl 
                  -style rpc 
                  -use literal 
                  -wsifEjbBinding true 
                  -jndiName HelloService2EJB 
                  -interfaceName oracle.demo.ejb.HelloServiceInf 
                  -jndiProviderUrl deployer:oc4j:localhost:23791/HelloService
                  -initialContextFactory oracle.j2ee.rmi.RMIInitialContextFactory
                  -className oracle.demo.hello.HelloImpl 
                  -classpath ${additional.class.path}:build/classes 

Example 9-8 Ant Task, Using wsifEjbBinding to Configure a Single EJB Port

<oracle:genWsdl
      output="wsdl"
      style="rpc"
      use="literal"
      wsifEjbBinding="true"
      jndiName="HelloService2EJB"
      jndiProviderUrl="deployer:oc4j:localhost:23791/HelloService"
      initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory"
      >
       <oracle:porttype
            interfaceName="oracle.demo.ejb.HelloServiceInf"
            className="oracle.demo.hello.HelloImpl">
       </oracle:porttype>
       <oracle:classpath>
            <pathelement path="${additional.class.path}"/>
            <pathelement location="build.ejb.dir"/>
       </oracle:classpath>
</oracle:genWsdl>

In these command line and Ant task examples:

  • genWsdl—Generates a WSDL and a JAX-RPC mapping file for assembling Web services bottom up from a Java interface.

  • output—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created.

  • style—For bottom up Web service assembly, this argument specifies the style attribute of the message format in the generated WSDL.

  • use—For bottom up Web service assembly, this argument specifies the use attribute of the message format in the generated WSDL.

  • wsifEJBBinding—Used in bottom up Web services assembly to add WSIF EJB bindings to the WSDL. If true, you must also specify the EJB's home interface className and jndiName.

  • jndiName—Specifies a JNDI name for an EJB.

  • jndiProviderUrl—Specifies the URL for the JNDI Provider. This is an optional argument that can be called by the genWsdl or ejbAssemble command when configuring an EJB WSIF port with wsifEjbBinding or wsifEjbPort.

  • porttype—This tag enables you to configure different interfaces to a Web service.

  • initialContextFactory—Specifies the name of the factory that will provide the initial context. This is an optional argument that can be called by the genWsdl or ejbAssemble command when configuring an EJB WSIF port with wsifEjbBinding or wsifEjbPort.

  • interfaceName—Specifies the name of a Java class (including the package name) that contains the service endpoint interface (SEI).

  • className—Specifies the name of the class (including the package name) that is the implementation class for the Web service.

  • classpath—Specifies the classpath that contains any user-created classes given to WebServicesAssembler. One reason to specify this argument is if you have already created some value type classes or exceptions and you do not want WebServicesAssembler to overwrite them.

See Also:

"Using WebServicesAssembler", in the Oracle Application Server Web Services Developer's Guide for more detailed information on these arguments.

How to Configure a Single EJB Port with wsifEjbPort

The wsifEjbPort argument can be used only in an Ant task. Although you typically use wsifEjbPort to specify WSIF EJB bindings for multiple ports, you can also use it to specify a single port. The argument has attributes that allow you to specify a WSIF port name, a class name, a JNDI name, a JNDI initial context, and a JNDI provider URL for each port. These attributes are passed to the ejb:address element in the WSDL. Table 9-2 describes the attributes that can be used by the wsifEjbPort argument. Except for jndiName, all of the attributes are optional.

Table 9-2 Attributes for the wsifEjbPort argument.

Attribute Description

className

Specifies the class name of the EJB's home interface. If you do not provide a value for this attribute, WebServicesAssembler will use the class name for the parent Ant task if it was specified.

initialContextFactory

Specifies the name of the factory that will provide the initial context. If you not provide a value for this attribute, the value in the jndi.properties file will be used.

jndiName

(required) Specifies the JNDI name for the EJB.

jndiProviderURL

Specifies the URL for the JNDI Provider. If you do not provide a value for this attribute, the value in the jndi.properties file will be used.

name

Specifies the name of the WSIF Port in the Web service. This name will be used to identify the WSIF port in the WSDL's port element.


The Ant task for genWsdl in Example 9-9 inserts WSIF EJB binding code into the WSDL's binding, binding operation, and port clauses. The HelloHome class used as the className attribute to the wsifEJBPort argument, contains a sayHello method that takes a greeting parameter of type String. The variable ${additional.class.path} represents the classpath.

Example 9-9 Using wsifEjbPort to Configure a Single EJB Port

<oracle:genWsdl
    output="wsdl"
    style="rpc"
    use="literal"  
    serviceName="${app.name}"
    >
    <oracle:porttype
         interfaceName="oracle.test.wsif.HelloServiceInf">
           <oracle:wsifEjbPort name="EjbPort"
            className="oracle.test.wsif.HelloHome"
            jndiName="HelloServiceBean"
            jndiProviderUrl="deployer:oc4j:localhost:23791/HelloService"
            initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory"
            />
    </oracle:porttype>
    <oracle:classpath> 
        <oracle:pathelement path="${additional.class.path}"/>
        <oracle:pathelement location="build/classes"/>
    </oracle:classpath>
</oracle:genWsdl>

In these command line and Ant task examples:

  • genWsdl—Generates a WSDL and a JAX-RPC mapping file for assembling Web services bottom up from a Java interface.

  • output—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created.

  • style—For bottom up Web service assembly, this argument specifies the style attribute of the message format in the generated WSDL.

  • use—For bottom up Web service assembly, this argument specifies the use attribute of the message format in the generated WSDL.

  • serviceName—Specifies the service name.

  • porttype—This tag enables you to configure different interfaces to a Web service.

  • interfaceName—Specifies the name of a Java class (including the package name) that contains the service endpoint interface (SEI).

  • wsifEJBPort—Allows you to specify WSIF Java bindings for multiple ports.

  • className—Specifies the name of the class (including the package name) that is the implementation class for the Web service.

  • jndiName—Specifies a JNDI name for an EJB.

  • jndiProviderUrl—Specifies the URL for the JNDI Provider. This is an optional argument that can be called by the genWsdl or ejbAssemble command when configuring an EJB WSIF port with wsifEjbBinding or wsifEjbPort.

  • initialContextFactory—Specifies the name of the factory that will provide the initial context. This is an optional argument that can be called by the genWsdl or ejbAssemble command when configuring an EJB WSIF port with wsifEjbBinding or wsifEjbPort.

  • classpath—Specifies the classpath that contains any user-created classes given to WebServicesAssembler. One reason to specify this argument is if you have already created some value type classes or exceptions and you do not want WebServicesAssembler to overwrite them.

See Also:

"Using WebServicesAssembler", in the Oracle Application Server Web Services Developer's Guide for more detailed information on these arguments.

Example 9-10 illustrates the WSIF EJB binding code that the previous example inserts into the WSDL's binding, binding operation, and port clauses.

Example 9-10 WSDL Extensions for WSIF EJB Bindings

...
<ejb:binding/>
    <format:typeMapping encoding="Java" style="Java">
        <format:typeMap typeName="xsd:string" formatType="java.lang.String"/>
    </format:typeMapping>
...
<operation name="sayHello">
    <ejb:operation 
         methodName="sayHello" 
         interface="remote" 
         parameterOrder="greeting" 
         returnPart="result"/>
... 
<port name="EjbPort" binding="tns:EjbPortBinding">
    <ejb:address  className="oracle.test.wsif.HelloHome"
        jndiName="HelloServiceBean"
        initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory"
        jndiProviderURL="deployer:oc4j:localhost:23791/HelloService"/>
</port>  
...

How to Configure Multiple EJB Ports with wsifEjbPort

Use the wsifEjbPort argument to define WSIF bindings for multiple EJB ports. This argument can be used by the ejbAssemble and the genWsdl Ant tasks. Example 9-11 illustrates the Ant task that creates a WSIF port named EjbPort and a SOAP port named SoapPort. The SOAP port is created by adding the <oracle:port name="... "/> subtask. The variable ${additional.class.path} represents the classpath. Table 9-2 describes the attributes that can be used by wsifEjbPort.

Example 9-11 Using wsifEjbPort to Configure Multiple EJB Ports

<oracle:genWsdl
    
    output="wsdl"
    style="rpc"
    use="literal" 
    serviceName="${app.name}"
    >
      <oracle:porttype interfaceName="oracle.test.wsif.HelloServiceInf"
        >
        <oracle:port name="SoapPort" uri="TestWsdlService"/>
        <oracle:wsifEjbPort name="EjbPort"
          className="oracle.test.wsif.HelloHome"
          jndiName="HelloServiceBean"
          jndiProviderUrl="deployer:oc4j:localhost:23791/HelloService"
          initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory"
        />
     </oracle:porttype>
    <oracle:classpath> 
        <oracle:pathelement path="${additional.class.path}"/>
        <oracle:pathelement location="build/classes"/>
    </oracle:classpath>
</oracle:genWsdl>

WSIF EJB Extensions to the WSDL

To comply with the WSIF Framework definition, OracleAS Web Services inserts code into the WSDL that allows an EJB to be represented as a Web service. Example 9-10 illustrates how additional bindings, binding operations, and port clauses are added to the WSDL to describe a WSIF service. Example 9-12 illustrates the corresponding XML schema definitions for these extensions.

Example 9-12 Schema Definitions to Support WSIF EJB Bindings

...
<!-- EJB binding --> 
<binding ... > 
    <ejb:binding/> 
    <format:typeMapping style="uri" encoding="..."/>? 
        <format:typeMap typeName="qname"|elementName="qname"
                   formatType="nmtoken"/>* 
    </format:typeMapping> 
    ...
    <operation>* 
        <ejb:operation 
            methodName="nmtoken" 
            parameterOrder="nmtoken"? 
            returnPart="nmtoken"?
            interface="home|remote"? />? 
        <input name="nmtoken"? />? 
        <output name="nmtoken"? />? 
        <fault name="nmtoken"? />? 
    </operation> 
</binding> 
... 
<service ... > 
    <port>* 
         <ejb:address 
             className="nmtoken" 
             jndiName="nmtoken" 
             initialContextFactory="nmtoken"?
             jndiProviderURL="url"?  /> 
    </port> 
</service> 
...

WSIF and Database Resources

To insert WSIF extensions for database resources into the WSDL, OracleAS Web Services provides two arguments that can be used with the aqAssemble, dbJavaAssemble, plsqlAssemble, sqlAssemble and genWsdl WebServicesAssembler commands.

As you assemble a Web service based on a database resource with the aqAssemble, dbJavaAssemble, plsqlAssemble, sqlAssemble, or genWsdl commands, the wsifDbBinding and wsifDbPort arguments allow you to create a direct invocation to the database by using a WSIF binding. Note that database WSIF clients must provide a JNDI setup where the data source for connecting to the database can be determined at runtime.

These arguments add the appropriate WSDL extensions that allow a WSIF client to access database resources exposed as a Web service.

See Also:

"WSIF SQL Extensions to the WSDL" for lists of the schema definitions that can be added to the WSDL to support WSIF database resource bindings.

To configure the WSIF database resource binding for a single port, you can use either the wsifDbBinding or wsifDbPort argument. To configure WSIF database resource bindings for multiple ports, you must use the wsifDbPort argument.

While the wsifDbBinding argument can be used either on the command line or in an Ant task, wsifDbPort can be used only in an Ant task.

The following sections describe how to configure WSIF endpoints for single and multiple database resource ports.

How to Configure a WSIF Endpoints Database Resource Ports

The WSIF endpoint for a single database resource port can be configured with wsifDbBinding or wsifDbPort.

How to Configure a Single Database Resource Port with wsifDbBinding

The wsifDbBinding argument can be used with aqAssemble, dbJavaAssemble, plsqlAssemble, sqlAssemble, and genWsdl WebServicesAssembler commands to specify the WSIF database resource bindings for a single port.

To establish the database connection, you must specify either dataSource or a combination of dbUser and dbConnection.

Table 9-3 Attributes for the wsifDbBinding and wsifDbPort Arguments

Attribute Description

className

(required) Specifies the name of the Java class generated by Oracle JPublisher. If you do not provide a value for this attribute, WebServicesAssembler will derive a value based on the port name.

dataSource

Specifies the JNDI location of the data source used by the Web service. This attribute is required if you do not provide dbConnection and dbUser attributes. For more information on the dataSource argument, see "datasource" in the "Database Assembly Commands" section of the Oracle Application Server Web Services Developer's Guide.

dbConnection

Specifies the JDBC URL for the database. If you specify dbConnection, you must also provide a value for dbUser. The dbConnection attribute might also be used at runtime in certain cases.

See "dbConnection" in the "Database Assembly Commands" section of the Oracle Application Server Web Services Developer's Guide for more information on this attribute.

dbUser

Specifies the database schema and password in the form user/password. The value of this attribute is employed only at code generation time to access the database.

If you specify dbUser, you must also provide a value for dbConnection. See "dbUser" in the "Database Assembly Commands" section of the Oracle Application Server Web Services Developer's Guide for more information on this attribute.

name

(required for wsifDBPort only) Specifies the port name.


  • If only the dataSource argument appears in an Ant task or on the command line, it will provide assembly time and runtime access to the database.

  • If only the dbConnection and dbUser arguments appear in an Ant task or on the command line, they will provide assembly time access to the database. In addition, the dbConnection attribute is used at runtime. See "How to Access the Database from a WSIF Client" for information on how the user name and password is set at runtime.

  • If the dbConnection, dbUser, and dataSource arguments appear in an Ant task or on the command line, then dbConnection and dbUser will be used for assembly time access to the database. The dataSource argument will be used for runtime access.

Example 9-13 illustrates a WebServicesAssembler command line for sqlAssemble that calls wsifDbBinding to configure a single port for a database resource. Example 9-14 illustrates the corresponding Ant task. These examples provides values for dbUser and dbConnection which will be entered into the <port> element of the WSDL. The useDataSource argument is specified as false: the value of the dataSource argument will not be used in the WSDL <port> element. The variables ${wsdemo.common.class.path}, ${additional.class.path}, and ${service.classes.dir} represent classpath elements.

Example 9-13 Command Line, Using wsifDbBinding to Configure a Single Database Resource Port

java -jar wsa.jar -sqlAssemble 
                  -dbUser scott/tiger 
                  -dbConnection jdbc:oracle:thin:@... 
                  -dataSource jdbc/OracleManagedDS
                  -appName SqlWsifTest 
                  -serviceName sqlwsif 
                  -output build 
                  -ear dist/SqlWsifTest.ear 
                  -style rpc 
                  -use literal 
                  -wsifDbBinding true 
                  -sqlstatement "getEname=select ename from emp" 
                  -sqlstatement "updateSal=update emp SET sal=sal+500 where
                                 ename=:{myname VARCHAR}"
                   -classpath ${CLASSPATH}:build/classes

Example 9-14 Ant Task, Using wsifDbBinding to Configure a Single Database Resource Port

<oracle:sqlAssemble 
    dbUser="scott/tiger" 
    dbConnection="jdbc:oracle:thin@…" 
    dataSource="jdbc/OracleManagedDS"
    appName="SqlWsifTest"
    serviceName="sqlwsif"
    output="build"
    ear="dist/SqlWsifTest.ear"
    style="rpc"
    use="literal"
    wsifDbBinding="true"
    > 
    <oracle:port name="sqlwsif" uri="SqlWsifTest" />
    <sqlstatement value="getEname=select ename from emp" /> 
    <sqlstatement value="updateSal=update emp SET sal=sal+500 where ename=:{myname VARCHAR}" />
    <oracle:classpath> 
        <oracle:pathelement path="${wsdemo.common.class.path}"/> 
        <oracle:pathelement path="${additional.class.path}"/> 
        <oracle:pathelement location="client/classes"/> 
        <oracle:pathelement location="${service.classes.dir}"/> 
    </oracle:classpath> 
</oracle:sqlAssemble>

In these command line and Ant task examples:

  • sqlAssemble—Generates Web services from SQL statements, including SQL queries and DMLs (Data Manipulation Language). To use this command, you must connect to a database.

  • dbUser—Specifies the database schema and password in the form of user/password.

  • dbConnection—Specifies the JDBC URL for the database.

  • dataSource—Specifies the JNDI location of the data source used by the Web services at runtime.

  • appName—Specifies the name of an application. Usually, this name is used as a base value for other arguments like context and uri.

  • serviceName—Specifies the service name.

  • output—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created.

  • ear—Specifies the name and location of the generated EAR.

  • style—For bottom up Web service assembly, this argument specifies the style attribute of the message format in the generated WSDL.

  • use—For bottom up Web service assembly, this argument specifies the use attribute of the message format in the generated WSDL.

  • wsifDbBinding—Used in bottom up Web services assembly to add WSIF SQL bindings to the WSDL. WebServicesAssembler will generate native WSIF SQL bindings in addition to SOAP bindings in the WSDL.

  • sqlStatement—Specifies the DML statement or SQL query to be published as a Web service.

  • classpath—Specifies the classpath that contains any user-created classes given to WebServicesAssembler. One reason to specify this argument is if you have already created some value type classes or exceptions and you do not want WebServicesAssembler to overwrite them.

See Also:

"Using WebServicesAssembler", in the Oracle Application Server Web Services Developer's Guide for more detailed information on these arguments.

Example 9-15 illustrates the WSIF database resource binding code that the previous example inserts into the WSDL's <port> element.

Example 9-15 WSDL Extensions for WSIF Database Resource Bindings

...
<service name="sqlwsif"> 
    <port name="JavaPort" binding="tns:JavaPortBinding"> 
        <java:address className="...User" 
            dataSource="jdbc/OracleManagedDS"/> 
    </port>
</service>
...

How to Configure a Single Database Resource Port with wsifDbPort

The wsifDbPort argument can be used only in an Ant task. Although you typically use wsifDbPort to specify the WSIF database resource bindings for multiple ports, you can also use it to specify a single port. The argument has attributes that allow you to specify a WSIF port name, a class name for the Java files generated by Oracle JPublisher, and database connection information. These attributes are passed to the java:address element of the WSDL's <port> element.

Table 9-3 describes the attributes that can be used by the wsifDbPort argument. Except for className and name, all of the attributes are optional.

  • If only the dataSource argument appears in an Ant task or on the command line, it will provide assembly time and runtime access to the database.

  • If only the dbConnection and dbUser arguments appear in an Ant task or on the command line, they will provide assembly time access to the database. In addition, the dbConnection attribute is used at runtime. See "How to Access the Database from a WSIF Client" for information on how the user name and password is set at runtime.

  • If the dbConnection, dbUser, and dataSource arguments appear in an Ant task or on the command line, then dbConnection and dbUser will be used for assembly time access to the database. The dataSource argument will be used for runtime access.

Example 9-13 illustrates the WebServicesAssembler command line for wsifDbPort which inserts WSIF database resource code into the WSDL's binding, binding operation, and port clauses. Example 9-16 illustrates the corresponding Ant task. In the wsifDbPort argument, the name of the port is set to JavaPort and the name of the JPublisher-generated Java class is oracle.generated.sqlwsifUser.

Example 9-16 Ant Task, Using wsifDbPort to Configure a Single Database Resource Port

<oracle:sqlAssemble 
    dataSource="jdbc/OracleManagedDS" 
    appName="SqlWsifTest"
    portName="sqlwsif"
    serviceName="sqlwsif"
    output="build"
    ear="dist/SqlWsifTest.ear"
    style="rpc"
    use="literal"
    >
    <oracle:port name="sqlwsif"  uri="SqlWsifTest" />
    <sqlstatement value="getEname=select ename from emp" />
    <sqlstatement value="updateSal=update emp SET sal=sal+500 where ename=:{myname VARCHAR}" />
    <oracle:wsifDbPort 
        name="JavaPort"
        className="oracle.generated.sqlwsifUser"
    /> 
    <oracle:classpath> 
        <oracle:pathelement path="${wsdemo.common.class.path}"/> 
        <oracle:pathelement path="${additional.class.path}"/> 
        <oracle:pathelement location="client/classes"/> 
        <oracle:pathelement location="service/classes"/> 
    </oracle:classpath> 
</oracle:sqlAssemble>

Example 9-17 illustrates the WSIF database resource binding code that the previous example inserts into the WSDL.

Example 9-17 WSDL Extensions for WSIF Database Resource Bindings

<service name="sqlwsif">           
    <port name="JavaPort" binding="tns:JavaPortBinding"> 
        <java:address className="oracle.generated.sqlwsifUser" 
            dataSource="jdbc/OracleManagedDS"/>            
    </port>
</service>

How to Configure Multiple Database Resource Ports with wsifDbPort

Use the wsifDbPort argument to define WSIF bindings for multiple database resource ports. This argument can be used in the Ant tasks for the aqAssemble, dbJavaAssemble, plsqlAssemble, sqlAssemble, and genWsdl commands.

Example 9-18 illustrates an Ant task that creates a SOAP port and a WSIF port. The port operations are based on the <sqlstatement value="..."/> subtasks. The wsifDbPort subtask creates the JavaPort port. The oracle:port subtask creates the SOAP port. The variables ${wsdemo.common.class.path}, ${additional.class.path}, and ${service.classes.dir} represent classpath elements. Table 9-3 describes the attributes that can be used by wsifDbPort.

Example 9-18 Ant Task, Using wsifDbPort to Configure Multiple Database Resource Ports

<oracle:sqlAssemble
        dbUser="scott/tiger"
        dbConnection="jdbc:oracle:thin:@${DB_HOST}:${DB_PORT}:${DB_SID}"
        dataSource="jdbc/OracleManagedDS"
        appName="wsifTest"
        portName="dbwsif"
        serviceName="dbwsif"
        output="build"
        ear="dist/wsifDbTest.ear"
        style="rpc"
        use="literal"
        >
        <oracle:port name="dbwsif"  uri="wsifDbTest"/>
        <sqlstatement value="getEname=select ename from emp" />
        <sqlstatement value="updateSal=update emp SET sal=sal+500 where
            ename=:{myname VARCHAR}" />
        <oracle:wsifDbPort name="JavaPort" 
                className="oracle.generated.sqlwsifUser"
        >
        <oracle:classpath>
            <oracle:pathelement path="${wsdemo.common.class.path}"/>
            <oracle:pathelement path="${additional.class.path}"/>
            <oracle:pathelement location="${client.classes.dir}"/>
            <oracle:pathelement location="${service.classes.dir}"/>
        </oracle:classpath> 
    </oracle:sqlAssemble>

In this Ant task example:

  • sqlAssemble—Generates Web services from SQL statements, including SQL queries and DMLs (Data Manipulation Language). To use this command, you must connect to a database.

  • dbUser—Specifies the database schema and password in the form of user/password.

  • dbConnection—Specifies the JDBC URL for the database.

  • dataSource—Specifies the JNDI location of the data source used by the Web services at runtime.

  • appName—Specifies the name of an application. Usually, this name is used as a base value for other arguments like context and uri.

  • portName—Specifies the name of a port in a WSDL document.

  • serviceName—Specifies the service name.

  • output—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created.

  • ear—Specifies the name and location of the generated EAR.

  • style—For bottom up Web service assembly, this argument specifies the style attribute of the message format in the generated WSDL.

  • use—For bottom up Web service assembly, this argument specifies the use attribute of the message format in the generated WSDL.

  • wsifDbPort—Enables you to define WSIF bindings for multiple database resource ports.

  • sqlStatement—Specifies the DML statement or SQL query to be published as a Web service.

  • classpath—Specifies the classpath that contains any user-created classes given to WebServicesAssembler. One reason to specify this argument is if you have already created some value type classes or exceptions and you do not want WebServicesAssembler to overwrite them.

See Also:

"Using WebServicesAssembler", in the Oracle Application Server Web Services Developer's Guide for more detailed information on these arguments.

WSIF SQL Extensions to the WSDL

To comply with the WSIF Framework definition, OracleAS Web Services inserts code into the WSDL that allows a database resource to be represented as a Web service. Example 9-15 illustrates how additional database resource bindings are placed in the WSDL. Specifically, the WSIF JavaPortBinding is further extended with the optional dataSource attribute. The presence of this attribute indicates that this is a database port and not a Java port. Example 9-19 illustrates the corresponding XML schema definitions for this extension.

Example 9-19 Schema Definitions to Support WSIF Database Resource Bindings

...
<definitions .... > 
 
    <!-- Java binding --> 
    <binding ... > 
        <java:binding/> 
        <format:typeMapping style="uri" encoding="..."/>? 
            <format:typeMap typeName="qname"|elementName="qname" formatType="nmtoken"/>* 
        </format:typeMapping> 
        <operation>* 
            <java:operation 
                methodName="nmtoken" 
                parameterOrder="nmtoken"? 
                returnPart="nmtoken"?
                methodType="instance|static|constructor"? />? 
            <input name="nmtoken"? />? 
            <output name="nmtoken"? />? 
            <fault name="nmtoken"? />? 
        </operation> 
    </binding> 
 
    <service ... > 
        <port>* 
             <java:address 
                 className="nmtoken" 
                 classPath="nmtoken"? 
                 classLoader="nmtoken"?
                 dataSource="nmtoken"?
        </port> 
    </service>  
</definitions>
...

Writing a WSIF Client

A WSIF client is similar to a DII client in that it does not rely on any pre-generated stub. The WSDL plays a central role for the WSIF client. Since the WSDL contains all of the information to invoke the service, it must be available to the client at runtime. The WSIF client must create the WSIF service, port, operation, and messages, before it actually invokes the operation with the messages.

The WSIF API, which is based on the abstract service description portion of the WSDL, contains methods for obtaining this information from the WSDL. The WSIF API is available from the Apache Software Group Web site.

http://ws.apache.org/wsif/

Note:

There is no WebServicesAssembler support for generating WSIF clients.

This section contains the following subsections:

Steps to Write a WSIF Client

To write a WSIF client, follow these general steps.

  1. Create a new instance of a WSIF service factory.

    The newInstance method of the org.apache.wsif.WSIFServiceFactory class instantiates a new WSIF service factory. For example:

    // create a service factory
    WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
    
  2. Create a WSIF service.

    Information in the WSDL file is used to build the WSIF service. The WSIFServiceFactory class provides a variety of getService methods to obtain the service definition from the WSDL. The location of the WSDL file can be specified either as a URL location available over HTTP, or as a file-based location available through the classLoader. Additional parameters for service creation are service name/namespace and portType/namespace. For example:

    WSIFService service = factory.getService( ... );
    
  3. Create the WSIF port, operation, and messages.

    Use the WSIF service to create the WSIF port. Use one of the WSIF API WSIFService.getPort methods to get the WSIF port for the port type that this factory supports. For example:

    WSIFPort port = service.getPort("portName");
    
  4. Create the WSIF operation.

    Use the WSIF port to create the WSIF operation. An operation is created using a service name or a combination of service name and input and output messages. There must be exactly one operation in this port's portType with this name. The WSIF API supports a variety of createOperation methods, depending on the type of J2EE component you are exposing as a Web service. For example:

    WSIFOperation operation = port.createOperation("operationName");
    
  5. Create the input, output, and fault messages.

    Use the WSIF operation to create the messages. The WSIFOperation interface in the WSIF API supports a variety of methods to create input, output, and fault messages. For example:

    WSIFMessage input = operation.createInputMessage();
    WSIFMessage output = operation.createOutputMessage();
    WSIFMessage fault = operation.createFaultMessage();
    
  6. Populate the input message.

    There are two possible ways to populate the message, depending on whether you will be invoking an RPC or a document-literal Web service.

    • To populate the input message for an RPC Web service, set the parts (defined in the WSDL) of the input message. For example, use one of the WSIFMessage.setObjectPart methods to allow the operation to pass a value to the service. You can also set message types using Java classes based on the type map, which is set by the service. In the following example, the name variable is taken from the WSDL's request message part for the operation.

      input.setObjectPart("name", "Duke");
      
    • To populate the input message for a document-literal Web service, the client must construct the SOAPElement object before setting the parts. This is illustrated in the following example. The parameter variable is taken from the WSDL's request message part for the sayHello operation.

      SOAPFactory soapfactory = SOAPFactory.newInstance(); 
      SOAPElement request = soapfactory.createElement("sayHelloElement", "ns0",
          "http://oracle.demo.hello/"); 
      SOAPElement nameChild = soapfactory.createElement("name"); 
      nameChild.addTextNode("Duke"); 
      request.addChildElement(nameChild); 
      input.setObjectPart("parameter", request) 
      
  7. Make the call to the service.

    Use one of the WSIF API "execute" methods to execute the operation. The signature allows for input, output and fault messages. The WSIF API supports a variety of "execute" methods, depending on the type of J2EE component you are exposing as a Web service. For example:

    operation.executeRequestResponseOperation( ... ); 
    

    The call can return a Boolean variable that is equal to true if the operation succeeds, or false otherwise. If the call fails, a fault message can be examined to determine the exact reason for the failure. The fault message is populated based on the SOAPBody:Fault element defined in the SOAP specification. If the call succeeds, the content of the output message can be extracted into Java classes based on the output message parts (similar to the population of the input messages).

Example 9-20 illustrates a sample DII client. The client performs an invocation on the HelloService's sayHello method, and passes "Duke" as the value for the name parameter. The WSDL that defines the service is deployed at http://localhost:8888/helloWSIFDii/helloWSIFDii?WSDL. The portType is the QName {http://hello.demo.oracle/}HelloInterface, where http://hello.demo.oracle/ is the portType namespace and HelloInterface is the port name. The name of the WSIF port is HelloServicePort and the name of the operation is sayHello. The executeRequestResponseOperation method makes the call to the service.

Example 9-20 Sample WSIF Client Code

import org.apache.wsif.*;
...
// create a service factory
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
 
// parse the WSDL
WSIFService service =
        factory.getService("http://localhost:8888/helloWSIFDii/helloWSIFDii?WSDL",
        null, null, "http://hello.demo.oracle/", "HelloInterface");

// create WSIF port, operation, and messages
WSIFPort port = service.getPort("HelloServicePort");
WSIFOperation operation = port.createOperation("sayHello");
WSIFMessage input = operation.createInputMessage();
WSIFMessage output = operation.createOutputMessage();
WSIFMessage fault = operation.createFaultMessage();
input.setObjectPart("name", "Duke");
 
// make the actual call to the service
operation.executeRequestResponseOperation(input, output, fault); 
...

Steps to Write a WSIF Client Using a Dynamic Proxy

A much simpler way of writing a WSIF client is to write it using a service endpoint interface. The WSIF runtime can create a corresponding implementation for you in the form of a dynamic proxy. This technique assumes that you already have a compiled service endpoint interface. The WSIF API provides a getStub method (org.apache.wsif.WSIFService.getStub) that gets the dynamic proxy that implements the interface.

The following steps summarize how to get the interface as a dynamic proxy.

  1. Create a new instance of a WSIF service factory.

    For example:

    WSIFServiceFactory factory = WSIFServiceFactory.newInstance(); 
    
  2. Create a WSIF service.

    For example:

    WSIFService service = factory.getService( ... );  
    
  3. Pass the service port name and the service endpoint interface class to the getStub method. Cast the dynamic proxy which is returned to the service endpoint interface.

    For example:

    HelloInterface stub = (HelloInterface) service.getStub( ... );  
    
  4. Call methods directly on the proxy that implements the interface.

    For example:

    String resp = stub.sayHello("Duke");  
    

Example 9-21 illustrates using the WSIF client as a dynamic proxy. The port name HttpSoap11 and the service endpoint interface class HelloInterface.class are passed to the getStub method. The returned dynamic proxy is cast to the HelloInterface service endpoint interface. Note that the stub parameter is also declared as type HelloInterface. Using the stub, you can then call methods on the interface directly.

Example 9-21 Using a WSIF Client as a Dynamic Proxy

// Create a service factory
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();

// Parse the WSDL
WSIFService service = factory.getService(serviceURL + "?WSDL", null, null,
        "http://hello.demo.oracle/", "HelloInterface");

// Call the getStub method with the port name and 
//    the service endpoint interface class.
// Cast the returned dynamic proxy to the service endpoint interface. 
HelloInterface stub = (HelloInterface) service.getStub("HttpSoap11", HelloInterface.class);

// Call methods directly on the interface
String resp = stub.sayHello("Duke");

How to Use genInterface to Generate a Service Endpoint Interface

The steps in the previous section assume that you have a WSDL and a service endpoint interface. If you do not have the service endpoint interface, one way to obtain it is to write it by hand, using the WSDL as a guide.

As an alternative to writing the interface by hand, you can pass the WSDL to the WebServicesAssembler genInterface command. The command will generate the service endpoint interface for you. This is especially convenient if the WSDL has a large number of operations that must be converted to methods.

When genInterface converts WSDL operations to Java methods, it will always make the first letter of the method name lowercase. If the original operation name in the WSDL begins with an uppercase character, this will cause a mismatch when you attempt to call methods on the proxy. Typically, a "Method does not exist" error will be returned.

To avoid this error, edit the service endpoint interface, if necessary, to ensure that method names exactly match the operation names in the WSDL, character-for-character.

How to Access the Database from a WSIF Client

The wsifDbBinding and wsifDBPort arguments add the appropriate bindings to the WSDL that allow a WSIF client to access database resources exposed as a Web service. The dataSource argument identifies the database that contains the resources.

If you omit the dataSource argument and only use dbConnection to identify the database URL at both code generation time and at runtime, then WebServicesAssembler generates its value into the WSDL file. To access the database, the WSIF client must pass the user name and password values at runtime. The generated code provides two methods to do this.

public void _setDataSourceUser(String);  
public void _setDataSourcePassword(String);  

The following are the complete paths of these methods. The CLASSNAME variable represents the value specified by the className argument. If className is not specified, it defaults to the value of portName.

CLASSNAME.setDataSourceUser(String user);
CLASSNAME.setDataSourceUser(String password);

If the dataSource argument is specified in the command or Ant task, then these two methods are not needed. The client will already have the privileges of accessing the database.

Example 9-22 illustrates a client for the Web service assembled by the Ant task in Example 9-14. The setDataSourceUser and setDataSourcePassword methods, which pass the user name and password to the server, are highlighted in bold.

Example 9-22 Client Code to Pass a User Name and Password to the Service

WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service = factory.getService(wsdlPath1, null, null, 
                      "http://generated.oracle/", "sqlwsif");
oracle.generated.sqlwsif stub = null;
stub = (oracle.generated.sqlwsif)
service.getStub("JavaPort", oracle.generated.sqlwsif.class);
stub.setDataSourceUser("scott");
stub.setDataSourcePassword("tiger");
System.out.println("Run Sql...");
String[] names = stub.getEname();

How to Add a Management Configuration to a WSIF Client

You can add a Web service management configuration for security, reliability, and auditing to a WSIF client.

A Web service management configuration on the WSIF client is useful only when it invokes a SOAP port or operation that has a matching Web service management configuration.

OracleAS Web Services does not support Web service management configuration for Java and EJB ports on the Web service side.

If a WSIF client which has a Web service management configuration communicates with a Java or an EJB port, then the Web service management configuration is ignored. The Web service management is used, however, if SOAP port is used to invoke the service.

The J2EE_HOME/config/wsif-wsm-config.xml file provides a template where you can specify outgoing management policies for the client. The wsif-wsm-config.xml file is based on the oracle-webservices-client-10_0.xsd schema.

By default, the wsif-wsm-config.xml file resides in the J2EE_HOME/config directory. If you change the name of the file or call it from another location, you can use the wsif.wsm.config.file system property to override its default name and location.

To create the management configuration and make it available to the WSIF client, you can use the wsif-wsm-config.xml file in either of the following ways:

  • edit the wsif-wsm-config.xml file in the J2EE_HOME/config directory, or

  • use the wsif-wsm-config.xml file as a template and store it in the location of your choice. Specify the new name and location of the file with the following system property

    -Dwsif.ws.config.file=<path to file>

Example 9-23 illustrates the contents of the wsif-wsm-config.xml file. Table 9-4 describes the elements in the file.

Example 9-23 WSIF Client Configuration File

<?xml version="1.0" encoding="UTF-8"?>
<oracle-webservice-clients xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="/oracle-webservices-client-10_0.xsd">
    <webservice-client>
        <service-qname namespaceURI="" localpart=""/>
        <port-info>
            <wsdl-port namespaceURI="" localpart=""/>
            <service-endpoint-interface></service-endpoint-interface>
            <stub-property>
                <name></name>
                <value></value>
            </stub-property>
            <call-property>
                <name></name>
                <value></value>
            </call-property>
            <runtime>
                <security>

<!-- Port-level Security configuration. For more information on security configuration elements, see the Oracle Application Server Web Services Security Guide. -->

</security>
                <reliability>

<!-- Port-level Reliability configuration. See "Port Level Reliability Elements on the Client" for a description of reliability configuration elements. -->

</reliability>
            </runtime>
            <operations>
                <operation name="">
                    <runtime>
                        <security>

<!-- Operation-level Security configuration. For more information on security configuration elements, see the Oracle Application Server Web Services Security Guide. -->

</security>

<!-- Operation level auditing configuration. See "How to Configure Auditing in a J2EE Client" for a description of auditing configuration elements. -->

<auditing/>
                        <reliability>

<!-- Operation-level reliability configuration. See "Operation Level Reliability Elements on the Client" for a description of reliability configuration elements. -->

</reliability>
                    </runtime>
                </operation>
            </operations>
        </port-info>
    </webservice-client>
</oracle-webservice-clients>

Table 9-4 describes the subelements for the <port-info> element. This element provides all of the information for a port within a service reference. You can specify either a service-endpoint-interface or wsdl-port to indicate the port that the container will use for container-managed port selection. If you specify both, then the container will use the wsdl-port value. If you do not specify wsdl-port or service-endpoint-interface, then the <port-info> property values will apply to all available ports.

The <port-info> element also contains subelements that let you specify quality of service features that are available for the port and its operations.

Table 9-4 Subelements of the <port-info> Element

Element Name Description

<call-property>

Defines the call property values applicable to the port defined by the <port-info> element. The name and value sub-elements of <call-property> are described in Table 9-5.

<operations>

Contains a sequence of elements, one for each operation. The <operation> subelement indicates an individual operation. Each of these subelements contain client-side quality of service configuration for a single operation provided by the referenced Web service.

The <operations> element is a subelement of the <port-info> element. For a description of <operations>, and its subelements, see "Adding OC4J-Specific Platform Information" in the Oracle Application Server Web Services Developer's Guide.

<runtime>

Contains client-side quality of service runtime information (security and/or reliability) applicable to all the operations provided by the referenced Web service. Each child element contains configuration for a specific feature.

<service-endpoint-interface>

Specifies the fully-qualified path to the service endpoint interface of a WSDL port. The container uses this port for container-managed port selection.

<stub-property>

Defines the stub property values applicable to the port defined by the <port-info> element. The name and value subelements of <stub-property> are described in Table 9-5.

<wsdl-port>

Specifies the namespaceURI and localpart of a port in the WSDL that the container will use for container-managed port selection.


Table 9-5 describes the name and value subelements of the <stub-property> and <call-property> elements.

Table 9-5 Subelements of <stub-property> and <call-property> Elements

Element Name Description

<name>

Defines the name of any property supported by the JAX-RPC Call or Stub implementation. See the output of the Javadoc tool for the valid properties for javax.xml.rpc.Call and javax.xml.rpc.Stub.

<value>

Defines a JAX-RPC property value that should be set on a Call object or a Stub object before it is returned to the Web service client.


How DII Clients of WSIF Services Can Get Message Headers

DII clients in WSIF can use methods in oracle.webservices.OracleCall, oracle.oc4j.wsif.providers.jaxrpc.WSIFPort_JaxRpc, and the public WSIF WSIFOperation API to retrieve HTTP request and response headers.

To retrieve response headers, use the WSIFOperation.executeRequestResponseOperation method to make the call to the service and the WSIFPort_JaxRpc.getCall method to retrieve the OracleCall object. The OracleCall.getResponseHeaders method returns a Vector which contains the SOAP response headers.

To retrieve request headers use the OracleCall.getHeaders method. This method also returns a Vector where the elements are the SOAP response headers. Typically, the headers are added to the Vector with the OracleCall.addHeaders method.

Example 9-24 illustrates DII client code for getting the response headers.

Example 9-24 Retrieving Response Headers in DII Client Code

...
operation.executeRequestResponseOperation(input, output, fault);
OracleCall call = (OracleCall) ((WSIFPort_JaxRpc) port).getCall();
Vector headers = call.getResponseHeaders();
if (Vector != null) {
    for(int i = 0;i < headers.size();i++) {
        Element header = (Element) headers.get(i);
        // do something with the header Element
        ...
    }
}
...

How to Add Message Attachments in WSIF

You can enable WSIF clients to pass message attachments. By default, WSIF supports passing attachments in a MIME-format message. The attachment itself is an object of type javax.activation.DataHandler, The mime:multipartRelated, mime:part and mime:content tags are used to describe the attachment in the WSDL.

Steps to Add Attachments in the WSIF Client with the WSIF API

To enable a WSIF client to add an attachment to a message, follow these general steps:

  1. Create a DataHandler object to encapsulate the attachment.

  2. Use the WSIF API's WSIFOperation.createInputMessage method to create an input message on the desired operation.

  3. Use the WSIF API's WSIFMessage.setObjectPart method to add the attachment to the message.

Example 9-25 illustrates how an attachment can be added to a message by using the WSIF API. In the code fragment, the JohnDoe.jpg attachment is saved as a DataHandler object. The operationName represents the operation that will be enabled to handle messages with attachments. The WSIFOperation's createInputMessage method creates an input message on the operation. The WSIFMessage's setObjectPart method attaches the attachment to the input message with the part name myAttachment.

Example 9-25 Adding an Attachment to a Message with the WSIF API

...
DataHandler dataHandler1 = new DataHandler(new URL("file:JohnDoe.jpg"));
WSIFOperation operation = port.createOperation(operationName);
WSIFMessage input = operation.createInputMessage();
input.setObjectPart("myAttachment", dataHandler1);
...

How to Add Attachments in a WSIF Client with the OracleCall API

The oracle.webservices.OracleCall API enables you to add attachments to messages that will be handled by WSIF clients. Using this technique, you save the attachment as a DataHandler object. You then add the attachment to the DII call object that you obtain from the WSIF port.

See Also:

The Oracle Application Server Web Services Java API Reference provides more information on the OracleCall API.

Example 9-26 illustrates how an attachment can be added to a message by using the OracleCall API. In the code fragment, the JohnDoe.jpg attachment is saved as a DataHandler object. The getCall method gets the DII call from the WSIF port. This call must be cast to a SOAP port, then to an OracleCall object. The OracleCall.addAttachment method adds the attachment to the SOAP message in the call. Note that the addAttachment method enables you to directly set the content-transfer-encoding and content-ID of the attachment MIME part.

Example 9-26 Adding an Attachment to a Message with the WSIF API

...
DataHandler dataHandler1 = new DataHandler(new URL("file:JohnDoe.jpg"));
OracleCall call = (OracleCall) ((WSIFPort_JaxRpc) port).getCall();
call.addAttachment(dataHandler1, "BASE64", "<ID1@photo>");
...

How to Retrieve Streamed Response Attachments in a WSIF Client

A WSIF client can use methods from the OracleCall and Attachments APIs to retrieve streaming attachments from the service.

See Also:

The Oracle Application Server Web Services Java API Reference provides more information on the Attachments and OracleCall API.

Example 9-27 illustrates sample WSIF client code to retrieve streamed response attachments from the server. In the sample, the getCall method gets the DII call from the WSIF port. This call must be cast to a SOAP port, then to an OracleCall object. The executeRequestResponseOperation method makes the call to the service. the OracleCall.getStreamedResponseAttachments method gets the streamed attachments from the OracleCall object. The getIncomingAttachments method captures the incoming streaming attachment as an Attachment object. The while loop iterates through the incomingAtts IncomingAttachments objects. The getDataHandler method gets the data handler from the Attachment object, and the attachment is retrieved as an input stream (getInputStream).

Example 9-27 WSIF Client Code to Retrieve a Streamed Response

...
OracleCall call = (OracleCall) ((WSIFPort_JaxRpc) port).getCall();
           operation.executeRequestResponseOperation(input, output, fault);
           Attachments atts = call.getStreamedResponseAttachments();
           IncomingAttachments incomingAtts = atts.getIncomingAttachments();
           while (incomingAtts.hasNextAttachment()) {
               Attachment att = incomingAtts.nextAttachment();
               InputStream is = att.getDataHandler().getInputStream();
               // read from InputStream is until no byte to read
               ...
           }

How to Add DIME-Packaged Attachments in a WSIF Client

By default, attachments to messages sent by DII and WSIF API clients are packaged in MIME format. To send a message attachment packaged in DIME format, set the boolean property WSIFConstants.DIME_PACKAGING to true within the WSIF message context. This property can be set on the context with the setBooleanPart method.

If the property is set to false (default) or is not used, then the WSIF message attachment will be packaged in MIME format.

Example 9-28 illustrates the use of the DIME_PACKAGING property. In the example, a new context object of type WSIFMessage is created and the DIME_PACKAGING property is applied to it. The context is then applied to the operation. Any attachments added to the message will be added in DIME format. The operation object used in the example is an instance of WSIFOperation.

Example 9-28 Adding a DIME Attachment in a WSIF Client

...
WSIFMessage context = new WSIFDefaultMessage();
context.setBooleanPart(WSIFConstants.DIME_PACKAGING, true);
operation.setContext(context);
...

Tool Support for WSIF

The Java J2EE Web Service wizard for Java classes in Oracle JDeveloper enables you to create WSIF bindings in addition to SOAP bindings for a Web service. Enter values for the class loader and class path that let the WSIF clients locate the service implementation class. These values are comparable to the classLoader and classPath parameters on the command line or Ant task.

The Web Service wizard for EJBs enables you to specify the initial context factory, JNDI provider URL, and JNDI name so that WSIF clients can locate the EJB through JNDI. These values are comparable to the initialContextFactory, jndiProviderUrl, and jndiName parameters on the command line or Ant task.

The Database Web Service wizard enables you to specify the user, connection, and datasource information necessary for defining WSIF bindings for a PL/SQL procedure.

Limitations

See "Using the Web Service Invocation Framework".

Additional Information

For more information on: