The Novell exteNd WSSDK is capable of exchanging SOAP messages using either an HTTP/HTTPS transport or using a JMS transport. This example illustrates how to develop a client and server using the Novell exteNd WSSDK that exchange SOAP messages using JMS under the covers. The key feature is that the client is practically the same regardless of the transport.
The key to configuring a JMS transport is the stub's binding, which must have a URL where the protocol is "jms". By default, the JMS transport will use a queue to exchange messages and the remainder of the URL is treated as the queue name, e.g. jms://myQueue.
If the location attribute in the soap:address element in the WSDL
service's port binding is a URL with a jms protocol, the stub generated by
wsdl2java will automatically be configured for the JMS transport. If
the location is a URL with an http protocol, you must manually set a jms binding
in the client:
Binding jms = new Binding("soap", "jms://myQueue");
stub.setCurrentBinding(jms);
This examples uses the familar hello world sample with a JMS transport. The WSDL document below has been modified slightly to introduce the concept of both a one-way and a two-way method:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="HelloService"
targetNamespace="http://www.jms2"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.jms2" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types/>
<message name="sayHelloRequest"/>
<message name="sayHelloResponse">
<part name="arg0" type="xsd:string"/>
</message>
<message name="notifyHelloRequest">
<part name="arg0" type="xsd:string"/>
</message>
<message name="notifyHelloResponse"/>
<portType name="Hello">
<operation name="sayHello">
<input message="tns:sayHelloRequest"/>
<output message="tns:sayHelloResponse"/>
</operation>
<operation name="notifyHello">
<input message="tns:notifyHelloRequest"/>
<output message="tns:notifyHelloResponse"/>
</operation>
</portType>
<binding name="HelloBinding" type="tns:Hello">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="sayHello">
<soap:operation soapAction="http://www.jms2/sayHello"/>
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.jms2" use="encoded"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.jms2" use="encoded"/>
</output>
</operation>
<operation name="notifyHello">
<soap:operation soapAction="http://www.jms2/notifyHello"/>
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.jms2" use="encoded"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.jms2" use="encoded"/>
</output>
</operation>
</binding>
<service name="HelloService">
<port binding="tns:HelloBinding" name="HelloPort">
<soap:address location="jms://queue/queue0"/>
</port>
</service>
</definitions>
The generated RMI for the above WSDL is shown below:
// Generated by Novell exteNd Web Services SDK 5.2
// On Wed Jun 09 11:16:15 EDT 2004
// From Hello.wsdl
package jms2;
public interface Hello
extends java.rmi.Remote
{
void notifyHello(java.lang.String arg0)
throws java.rmi.RemoteException;
java.lang.String sayHello()
throws java.rmi.RemoteException;
}
The remote interface has the usual sayHello method, which is a
two-way method returning a string. It also has a notifyHello method,
which is a one-way method that simply sends a message to a JMS destination.
The client application is very similar to the SOAP/HTTP
client. We create the service and the stub in the usual
fashion and invoke the one-way method. Please note that if your JMS provider
requires any special configuration, you should use the configuration properties
available in the
stub
base class. As an example, the JMS_QUEUE_REPLY_JNDI property must
be set before invoking two-way methods.
package jms2;
import javax.naming.InitialContext;
import com.sssw.jbroker.web.portable.Stub;
public class Client
{
public static void main(String[] args) throws Exception
{
| // get the initial context
| InitialContext ctx = new InitialContext();
|
| // lookup the service for Hello
| HelloService svc = (HelloService)
| ctx.lookup("xmlrpc:soap:jms2.HelloService");
|
| // get the hello stub
| // this stub is already configured with a jms binding
| Hello hello = (Hello) svc.getHelloPort();
|
| // send a message oneway
| hello.notifyHello("Hello");
|
| // set the replyTo destination
| ((Stub)hello)._setProperty(Stub.JMS_QUEUE_REPLY_JNDI, "queue/queue1");
|
| // send a message and wait for a response
| System.out.println(hello.sayHello());
}
}
The SOAP message sent out by the client using Novell exteNd WSSDK's JMS transport must be processed by a message listener, which is consuming message from the queue where the SOAP message was sent to, and which is possibly sending response messages on the replyTo queue. Below is a simply queue message listener that looks for messages on "queue0" and responds to the reply queue if the replyTo header field is set:
package jms2;
import javax.jms.*;
import javax.naming.*;
public class MessageBean implements MessageListener, ExceptionListener
{
public static void main(String[] args) throws Exception
{
| // construct the message listener
| MessageBean bean = new MessageBean();
|
| // wait for messages
| System.out.print("waiting for messages ...\n");
| synchronized (bean) { bean.wait(); }
|
| // close the queue connection
| bean.close();
}
public MessageBean() throws Exception
{
| // get the initial context
| InitialContext ctx = new InitialContext();
|
| // lookup the queue object
| Queue queue = (Queue) ctx.lookup("queue/queue0");
|
| // lookup the queue connection factory
| QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.
| lookup("queue/connectionFactory");
|
| // create a queue connection
| _queueConn = connFactory.createQueueConnection();
|
| // create a queue session
| _queueSession = _queueConn.createQueueSession(false,
| Session.AUTO_ACKNOWLEDGE);
|
| // create a queue receiver
| QueueReceiver queueReceiver = _queueSession.createReceiver(queue);
|
| // set an asynchronous message listener
| queueReceiver.setMessageListener(this);
|
| // set an asynchronous exception listener on the connection
| _queueConn.setExceptionListener(this);
|
| // start the connection
| _queueConn.start();
}
public void close() throws JMSException
{
| _queueConn.close();
}
public void onMessage(Message message)
{
| try {
| | TextMessage tm = (TextMessage) message;
| | System.out.println("\n" + tm.getText());
| | Queue replyTo = (Queue) message.getJMSReplyTo();
| | if (replyTo != null) {
| | | System.out.println("\nsending reply to " + replyTo);
| | | QueueSender sender = _queueSession.createSender(replyTo);
| | | TextMessage reply = _queueSession.createTextMessage(_response);
| | | sender.send(reply);
| | | sender.close();
| | }
| } catch (JMSException jex) {
| | System.err.println("failed to send: " + jex.getMessage());
| }
|
}
public void onException(JMSException exception)
{
| System.err.println("an error occurred: " + exception);
}
private final QueueSession _queueSession;
private final QueueConnection _queueConn;
private final static String _response =
"<Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'" +
" xmlns='http://schemas.xmlsoap.org/soap/envelope/'" +
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'" +
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
" xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'>" +
" <SOAP-ENV:Body>" +
" <ns1:sayHelloResponse" +
" SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'" +
" xmlns:ns1='http://www.jms2'>" +
" <result xsi:type='xsd:string'>Hello World!</result>" +
" </ns1:sayHelloResponse>" +
" </SOAP-ENV:Body>" +
"</Envelope>";
}
In order to build and run applications that use Novell exteNd WSSDK's JMS transport, a JMS provider must be available. You can for instance use the Novell exteNd Messaging Platform's JMS server. Please refer to the README for additional details on building and running this example.
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.