|
Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide
10g Release 3 (10.1.3) B14428-01 |
|
![]() Previous |
![]() Next |
A client never accesses an MDB directly: rather, the client accesses an MDB by sending a message through the JMS destination (queue or topic) associated with the MDB.
This section describes:
To send a message to a JMS destination using EJB 2.1:
Look up both the JMS destination (queue or topic) and its connection factory.
You can look up these resources using a predefined logical name (see "Configuring an Environment Reference to a JMS Destination or Connection Resource Manager Connection Factory") or the explicit JNDI name you defined when you configured your JMS provider (see "Configuring an EJB 2.1 MDB to Use a Non-J2CA Message Service Provider").
Oracle recommends that you use logical names as shown in this procedure and its examples.
Use the connection factory to create a connection.
If you are receiving messages for a queue, then start the connection.
Create a session over the connection.
Use the retrieved JMS destination to create a sender for a queue or a publisher for a topic.
Create the message.
Send the message using either the queue sender or the topic publisher.
Close the queue session.
Close the connection.
Example 29-24 shows how a servlet client sends a message to a queue.
Example 29-25 shows how a JSP client sends a message over a topic.
Example 29-24 Servlet Client Sends Message to a Queue
public final class testResourceProvider extends HttpServlet
{
private String resProvider = "myResProvider";
private HashMap msgMap = new HashMap();
Context ctx = new InitialContext();
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
doPost(req, res);
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
// Retrieve the name of the JMS provider from the request, which is to be used in creating
// the JNDI string for retrieval
String rp = req.getParameter ("provider");
if (rp != null) resProvider = rp;
try
{
// 1a. Look up the Queue Connection Factory
QueueConnectionFactory qcf = (QueueConnectionFactory)
ctx.lookup (
"java:comp/resource/" + resProvider + "/QueueConnectionFactories/myQCF"
);
// 1b. Lookup the Queue
Queue queue = (Queue)
ctx.lookup (
"java:comp/resource/" + resProvider + "/Queues/rpTestQueue"
);
// 2a. Create queue connection using the connection factory.
QueueConnection qconn = qcf.createQueueConnection();
// 2a. We're receiving msgs, so start the connection.
qconn.start();
// 3. create a session over the queue connection.
QueueSession sess = qconn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
// 4. Since this is for a queue, create a sender on top of the session.
//This is used to send out the message over the queue.
QueueSender snd = sess.createSender (q);
drainQueue (sess, q);
TextMessage msg = null;
/* Send msgs to queue. */
for (int i = 0; i < 3; i++)
{
// 5. Create message
msg = sess.createTextMessage();
msg.setText ("TestMessage:" + i);
// Set property of the recipient to be the MDB
// and set the reply destination.
msg.setStringProperty ("RECIPIENT", "MDB");
msg.setJMSReplyTo(q);
//6. send the message using the sender.
snd.send (msg);
// You can store the messages IDs and sent-time in a map (msgMap),
// so that when messages are received, you can verify if you
// *only* received those messages that you were
// expecting. See receiveFromMDB() method where msgMap gets used
msgMap.put( msg.getJMSMessageID(), new Long (msg.getJMSTimestamp()) );
}
// receive a reply from the MDB.
receiveFromMDB (sess, q);
//7. Close sender, session, and connection for queue
snd.close();
sess.close();
qconn.close();
}
catch (Exception e)
{
System.err.println ("** TEST FAILED **"+ e.toString());
e.printStackTrace();
}
finally
{
}
}
/*
* Receive any msgs sent to us via the MDB
*/
private void receiveFromMDB (QueueSession sess, Queue q)
throws Exception
{
// The MDB sends out a message (as a reply) to this client. The MDB sets
// the receipient as CLIENT. Thus, we will only receive msgs that have
// RECIPIENT set to 'CLIENT'
QueueReceiver rcv = sess.createReceiver (q, "RECIPIENT = 'CLIENT'");
int nrcvd = 0;
long trtimes = 0L;
long tctimes = 0L;
// First msg needs to come from MDB. May take a little while
//Receiving Messages
for (Message msg = rcv.receive (30000); msg != null; msg = rcv.receive (30000))
{
nrcvd++;
String rcp = msg.getStringProperty ("RECIPIENT");
// Verify if msg in message Map
// We check the msgMap to see if this is the message that we are expecting.
String corrid = msg.getJMSCorrelationID();
if (msgMap.containsKey(corrid))
{
msgMap.remove(corrid);
}
else
{
System.err.println ("** received unexpected message [" + corrid + "] **");
}
}
rcv.close();
}
/*
* Drain messages from queue
*/
private int drainQueue (QueueSession sess, Queue q)
throws Exception
{
QueueReceiver rcv = sess.createReceiver (q);
int nrcvd = 0;
// First drain any old msgs from queue
for (Message msg = rcv.receive(1000); msg != null; msg = rcv.receive(1000))
nrcvd++;
rcv.close();
return nrcvd;
}
}
Example 29-25 JSP Client Sends Message to a Topic
<%@ page import="javax.jms.*, javax.naming.*, java.util.*" %> <% //1a. Lookup the MessageBean topic jndiContext = new InitialContext(); topic = (Topic)jndiContext.lookup("rpTestTopic"); //1b. Lookup the MessageBean Connection factory topicConnectionFactory = (TopicConnectionFactory) jndiContext.lookup("myTCF"); //2 & 3. Retrieve a connection and a session on top of the connection topicConnection = topicConnectionFactory.createTopicConnection(); topicSession = topicConnection.createTopicSession(true,Session.AUTO_ACKNOWLEDGE); //5. Create the publisher for any messages destined for the topic topicPublisher = topicSession.createPublisher(topic); //6. Send out the message for (int ii = 0; ii < numMsgs; ii++) { message = topicSession.createBytesMessage(); String sndstr = "1::This is message " + (ii + 1) + " " + item; byte[] msgdata = sndstr.getBytes(); message.writeBytes(msgdata); topicPublisher.publish(message); System.out.println("--->Sent message: " + sndstr); } //7. Close publisher, session, and connection for topic topicPublisher.close(); topicSession.close(); topicConnection.close(); %> Message sent!
To send a message to a J2CA destination using EJB 2.1:
Look up both the J2CA connection factory.
You can look up this resource using a predefined logical name (see "Configuring an Environment Reference to a JMS Destination or Connection Resource Manager Connection Factory") or the explicit JNDI name you defined when you configured your JMS provider (see "Configuring an EJB 2.1 MDB to Use a Non-J2CA Message Service Provider").
Oracle recommends that you use logical names as shown in this procedure and its examples.
Obtain a javax.resource.cci.ConnectionFactory.
If the EIS is a JMS message service provider, there will likely be connection factory choices for queue or topic. For example, the Oracle JMS Connector offers a QueueConnectionFactory and a TopicConnectionFactory.
Use the factory to obtain a javax.resource.cci.Connection.
Use the connection to obtain a javax.resource.cci.Interaction.
Configure the interaction and use Interaction method execute to send the message.