The Web Services Invocation Framework (WSIF) provides a Java API for invoking web services,
independent of the format of the service, or the transport protocol
through which it is invoked.
Before you begin
WSIF includes an EJB provider for
EJB invocation that uses the Remote Method Invocation over Internet
Inter-ORB Protocol (RMI-IIOP). However, for EJB(IIOP)-based web service
invocation, invoke RMI-IIOP Web
services using JAX-RPC instead.
Ensure that your application
uses only one thread to call WSIF.
About this task
The WSIF API supports the invocation of Web Services
Description Language (WSDL)-defined web services. WSIF is intended
for use in both WSIF clients and web service intermediaries.
The
WSIF API is driven by the abstract service description in WSDL; it
is completely independent of the binding used. This independence makes
the API more natural to work with because it uses WSDL terms to refer
to message parts, operations, and other items.
The WSIF API
was designed for the WSDL usage model:
- Select a port that supports the port type that you need.
- Invoke the operation by providing the necessary abstract input
message consisting of the required parts, without worrying about how
the message is mapped to a specific binding protocol.
Other web service APIs, for example SOAP APIs, are not
designed on WSDL, but for a specific binding protocol with its associated
syntax; for example, target URIs and encoding styles.
The main
WSIF API interfaces are described in the following procedure. For
additional technical details of the WSIF API, see the generated API
documentation that is supplied with WSIF (see the Apache WSIF website).
- Create a message for sending to a port through the WSIFMessage
interface.
In WSDL, a message describes the abstract
type of the input or output to an operation. The corresponding WSIF
class is WSIFMessage, which represents in memory the input or output
of an operation. The WSIFMessage interface separates the representation
of the data from the abstract type defined by WSDL.
A WSIFMessage
class is a container for a set of named parts. WSIFMessage classes
can be sent between Java Virtual
Machines (JVMs).
- Choose whether to represent the WSIF message at run
time as a Java class or as XML.
There are two natural ways to represent a WSDL message in
a runtime environment:
- The generated Java class,
based on a WSDL to Java mapping
such as that provided by a Java API
for XML-based remote procedure call (JAX-RPC).
- The XML representation of the data, for example using SOAP Encoding.
Each option offers benefits in different scenarios. The Java class is the natural approach
when WSIF is used in a standard Java client.
However, in other scenarios where WSIF is used in an intermediary,
it might be more efficient to keep a WSDL message in the SOAP encoded
format. The style used to define messages must be consistent within
the message, so all the parts in one message must be consistent. A
string -
getRepresentationStyle() - always returns
null.
This indicates that parts on this WSIFMessage class are represented
as Java objects.
- Get and set the parts of the WSIF message.
You
add parts to a WSIFMessage class with the setObjectPart or setTypePart
methods. Each part is named. Part names within a message are unique.
If you set a part more than once, the last setting is the one that
is used.
You retrieve parts by name from a WSIFMessage class
with the getObjectPart or getTypePart methods.
If the named part does not exist, the method returns a WSIFException
error.
You can use Iterators to retrieve parts from the message
through the getParts() and getPartNames() methods.
The order
in which you set the parts is not important, but the message implementation
might be more efficient if the parts are set in the parameter order
specified by WSDL.
WSIFMessage classes are cloneable and serializable.
If the parts set are not cloneable, the implementation can try to
clone them using serialization. If the parts are not serializable
either, then a CloneNotSupportedException exception is thrown if cloning
is attempted.
- Set the WSIF message name.
In addition
to the containing parts, a WSIFMessage class also has a message name.
This is required for operation overloading, which is supported by
WSDL and WSIF.
For more information about the WSIFMessage interface (/wsi/org/apache/wsif/WSIFMessage.html)
see the generated API documentation that is supplied with WSIF.
- Find a port factory or service through the WSIFService
interface and the WSIFServiceFactory class.
The WSIFService
interface is a port factory that models and supports the WSDL approach
in which a service is available on one or more ports. The factory
hides the implementation of the port. WSIF supports dynamic ports
that are based on a particular protocol and transport and configured
using the WSDL at run time. For example, the dynamic SOAP port can
invoke any SOAP service based on the WSDL description of that service,
so you can hide and modify the set of available ports at run time.
To
find a service from a WSDL document at a web address, or from a code-generated
code base, use the WSIFServiceFactory class.
- Invoke an operation through the WSIFPort interface and
the WSIFOperation interface.
A WSIFPort interface handles
the details of invoking an operation. The port provides access to
the implementation of the service.
A WSDL document can provide
many different WSDL bindings, and these bindings can drive multiple
ports. The client can choose a port, the service stub can choose
a port, or WSIF can choose a default port.
The port offers an
interface to retrieve an Operation object. A WSIFOperation interface
offers the ability to run the given operation.
If the port
is serialized and deserialized at a later time, WSIF ensures that
the client provides the correct information to the server to identify
the instance. If the server instance is no longer available, the server must
decide whether to create a fault or provide a new instance. That behavior
can depend on the type of service. For example, for an enterprise
bean, the WSIFPort interface stores the EJB Home and uses it to select
the bean before each invocation. The client is responsible for serializing
or maintaining the port instance if it requires instance support.
The client must create a new operation and messages for each invocation.