Quick review of the basics first, An Axis2 user has couple of options to interact with a Web service using Axis2 client API.
- One can generate stubs using the WSDL of the service and use it to invoke the Web service. These stubs are analogues to stubs found in RMI that can be used to do remote method invocations. But unlike RMI, WSDL2Java generated code is usually the easiest way to interact with a Web service. Read the User's Guide found in Apache Axis2 Web site for more information on generating stubs to invoke Web services.
- You can use either ServiceClient or OperationClient API to invoke a Web service. Let's see how these can be used to invoke a Web service.
ServiceClient and OperationClient
Both ServiceClient and OperationClient classes enable you to send and receive xml messages. ServiceClient API is much easier to use, but provides less flexibility compared to OperationClient. The minimum information that you need to use ServiceClient is:
- The url where the Web service is hosted (target endpoint reference) and
- The body of SOAP message you need to send
ServiceClient only accepts the payload of the SOAP message that will be sent. But if you need to control the whole of SOAP message, to send and to tweak the internals of Axis2 client which is used to send your request, then you need to use OperationClient.
Basically, the design was to make the common case easier to use. Service Client is the most basic API and it fulfills the above requirement. Let's look at some examples to understand this a bit more.
Using Service Client
1. Options options = new Options();
2. options.setTo(new EndpointReference("http://address-to-webservice.org/MyService/MyOperation"));
3. ServiceClient sender = new ServiceClient();
5. OMElement result = sender.sendReceive(xmlPayload);
Line 1 : First you need to create an instance of
Options , as the name implies, is used to pass user options in to Axis2 client engine. Options you set using
Options object will help you tweak how the Axis2 engine works. (Refer Reference Guide to Apache Axis2 Client API Parameters for more information about the options that can be set using Axis2 Client API properties)
Line 2 : Set the target endpoint address using
options.setTo(targetEPR) method. Axis2 models information about all the endpoints around the concept of "Endpoint Reference" as defined in WS-Addressing Specification. In Axis2 we send messages to endpoints which has, at least an address which is an IRI.
Line 3-4 : Then create an instance of
ServiceClient and add the options to
Lines 5 : After that, its just a matter a of invoking the Web service passing the payload of the request message. Your XML payload must be created using AXIOM. AXIOM (AXis Object Model) is a fast and memory efficient XML object model which is based on pull parsing (For more information about AXIOM, read the AXIOM Tutorial found in AXIOM web site).
The method we used in
ServiceClient above is
sendReceive() . You invoke this method in order to invoke a Web service method which has a response. But if you need to invoke a method which does not return anything, then you can use either
fireAndForget() will just call the Web service on the other end, but doesn't wait to get an acknowledgment (transport level) for successful invocation.
on the other hand, waits for an acknowledgment which mostly comes through transport specific methods. You can select either one of those methods depending on the expected reliability of the invocation. In addition to that, you can prevent your client code from blocking until you get a response from the invoked Web service.
sendReceiveNonBlocking method enables you to register an instance of Callback interface and continue to work after the method invocation. Axis2 engine, calls the
onComplete method of the Callback object once it receives the response message. Non-blocking invocations are particularly useful in operations that take considerable amount of time to get the response back or to improve user experience in GUI based applications.
Using Operation Client API
You can use Operation Client if you want more control during the invocation. Typically you need to work with the Message Context. Axis2 creates an instance of Message Context for each and every SOAP message handled inside the engine. Message Context encapsulates a SOAP message and it has most of the information required to process the message. Axis2 engine is a stateless piece of code which executes according to the information found inside the Message Context.
Operation Client enables user to directly access or pass-in a Message Context so that user has the ability to set numerous parameters to be used during an invocation. User can even set a complete SOAP envelope to the message context, created by any means he likes. (Service Client API has means to set the content of body and it has
addHeader()) method to add headers to the SOAP messages. So Service Client user can also customize the SOAP message, to some extent, just like the Operation Client user.)
You need to know a bit about the concept of MEP (Message Exchange Pattern) to use Operation Client API.
Message Exchange Pattern (MEP)
During a request-response invocation, we first send a SOAP message to the Web service and it then returns back another SOAP message to us. From the Web service's point of view, it receives one incoming message (IN message) and sends out one message (OUT message). This is a pattern and we name this message exchange as IN-OUT MEP. Similarly, there can be another Web service which simply accepts messages from client. For example, you can register with a new alert system by sending a subscription request message (assume, you will become a member as soon as you send this request and server doesn't send a confirmation message). In this case you are working with an IN-only MEP.
In simple terms, MEP is a template that establishes a pattern for the exchange of messages between two communicating parties.
Having understood the concept of MEPs, let's look at how Operation Client can be used to invoke an IN-OUT Web service, hosted in a remote machine.
1. ServiceClient client = new ServiceClient();
2. Options options = new Options();
5. MessageContext msgctx = new MessageContext();
7. ....................... // write your custom code here
8. OperationClient opClient = client.createClient(ServiceClient.ANON_OUT_IN_OP);
11. MessageContext responseMsgCtx = opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
12. SOAPEnvelope responseEnvelope = response.getEnvelope();
Lines 1-4 : The first four lines of the code is same as you saw above, in using ServiceClient section.
Lines 5-6 : Then we need to create an instance of
MessageContext and attach your custom SOAP message to it.
Line 8 : After which you need to create an instance of the operation client using the service client object created earlier. Unlike the service client API which allows you to work with multiple MEPs, only one
OperationClient exists for a particular MEP. You need to pass the name of the MEP to the
createClient method of
ServiceClient (see line # 8).
OperationClient lets you to create the same Service and Operation hierarchy available in the server side, in the client side as well. But if you do not want to do complex operations, Axis2 will create an anonymous service and operation for your invocation. Even if the operation client created corresponds to an anonymous service, the operation client instance returned is capable of handling any OUT-IN invocation.
Lines 9-10 : Once you add the message context to the operation client instance using
addMessageContext method, then its just a matter of invoking the execute method of operation client. You can do blocking invocation by passing "true" to the execute method.
Line 11 : OperationClient API is a generic API for all the MEPs. OperationClient has different implementations for different MEPs, but it is transparent to the user. So if you need to get the response message, you need the message label for the
getMessageContext() method to get the response message context.
Line 12 : Get the response SOAP envelope from the message context.
In addition to Service and Operation clients, Axis2 has
RPCServiceClient API as well, but it is not considered as part of the base client API. RPC Service Client can take an array of java beans and the Objects of primitive types (Integer, Boolean, etc.) and the name of the operation during an invocation. It then serializes those java beans properly and sends out the SOAP message.
This is a basic introduction to the usage of different client APIs available in Apache Axis2. Service Client and Operation Client has lots of options to control the invocation and you are encouraged to read the Axis2 Javadocs for more information about them.
Eran Chinthaka, Senior Software Engineer, WSO2 Inc. chinthaka at wso2 do org