JMS転送の使用

Novell exteNd WSSDKでは HTTP/HTTPSプロトコルまたはJMSプロトコルのいずれかを使用してSOAPメッセージを交換できます。 この例では、Novell exteNd WSSDKを使用してクライアントおよびサーバを開発する方法について説明します。Novell exteNd WSSDKは、JMSを使用して背後でSOAPメッセージを交換します。 主な特徴は、転送に関わらずクライアントが事実上同じであることです。

JMS転送を設定する鍵は、スタブのバインドであり、プロトコルが「jms」であるURLを保持する必要があります。 デフォルト設定では、JMS転送がキューを使用してメッセージを交換し、URLの残りの部分がキューの名前、たとえばjms://myQueueとして処理されます。

WSDLサービスのポートバインド内のsoap:address要素の場所属性がjmsプロトコル付きURLである場合、rmi2soapによって生成されたスタブはJMS転送用に自動的に設定されます。 場所がhttpプロトコル付きURLである場合、クライアントにjmsバインドを手動で設定する必要があります。

   Binding jms = new Binding("soap", "jms://myQueue");
   stub.setCurrentBinding(jms);

1 Hello WSDL

この例では、よく知られているhello worldのサンプルにJMS転送を使用します。 次のWSDLドキュメントは、一方向および双方向メソッドの両方のコンセプトを導入するために多少修正されています。
<?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>

2 Hello Remoteインタフェース

上のWSDLに対して生成されたRMIを次に示します。
// Generated by Novell exteNd Web Services SDK 5.0
// On Thu Aug 28 16:02:52 EDT 2003
// 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;
}
Remoteインターフェースには、文字列を返す双方向メソッドである、おなじみのsayHelloメソッドがあります。 また、メッセージをJMSの宛先に送信する一方向メソッドであるnotifyHelloメソッドがあります。

3 クライアント

クライアントアプリケーションはSOAP/HTTP クライアントとほとんど同じです。 通常の方法でサービスおよびスタブを作成し、一方向メソッドを起動します。 JMSプロバイダが特別設定を必要とする場合、スタブベースクラスで利用できる設定プロパティを使用する必要があります。 たとえば JMS_QUEUE_REPLY_JNDI プロパティは双方向メソッドを呼び出す前に設定する必要があります。
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());
    }
}

4 Message Beanの実装

Novell exteNd WSSDKのJMS転送を使用してクライアントにより送信されたSOAPメッセージは、メッセージリスナによって処理される必要があります。メッセージリスナはSOAPメッセージの送信先であるキューからメッセージを消費し、可能な限りreplyToキューで応答メッセージを送信します。 簡単なメッセージリスナを次に示します。このメッセージリスナは、replyToヘッダフィールドが設定されている場合「queue0」でメッセージを検索し、返信キューに応答します。
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:xsd='http://www.w3.org/2001/XMLSchema'" +
        " 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>";
}
Novell exteNd WSSDKのJMS転送を使用するアプリケーションを作成し、実行するには、JMSプロバイダを利用する必要があります。 たとえば、jBroker製品ファミリーであるjBroker MQを使用できます。
Copyright © 2000-2003, Novell, Inc.All rights reserved.