The JMS API is used to send messages, it is a standard way to access the Message Oriented Middleware in Java.
In JMS the resources are to JDBC DataSource; these are created outside from the code and stored in JNDI. The two administrative object that we need for JMS are the javax.jms.ConnectionFactory and javax.jms.Destination that encapsulates all the configuratio informations needed to connect to MOM. Both are retrieved using the dependency injection with the @Resource annotation.
With EJB 3 retrieving resources is so easy: you don't have to to configure deployment descriptors to create resource references. In the next picture I show you how I inject these two objects:
To create and send a message with jms we need an object that connects to the MOM and this object is javax.jms.Connection that uses the createConnection() method from the connection factory we just injected. Then we need a Session to be used to send and receive messages; to create a session, a task-oriented context, we use the method createSession() of the connection object. This method takes two parameters: the first is used to specify if the session is transactional or not and the second specifies the acknowledge mode.
The session is not directly used to send and reveive the message; insted a producer is used to do so, and to create the producer we call at the createProducer() method of the session object. Which object is used to send the message? We use our injected destination: the ConfirmMailQueue.
Now we can create and populate the javax.jms.Message to be sent. In my message I send the UserBean that is registering to the application as I can send him the registration confirmation email. To do so I use the method createObjectMessage() from the javax.jms.ObjectMessage object and include my object into the message using the setObject() method. Now I am ready to send the message using the send method from the producer object:
After sending the message we close the resources used during the transaction: the producer and the session.
If everything goes well, our message has been sent to the queue that now we are going to see how it works.
The MDB are a great solution to send messages on J2EE.
It supports multithreading, it can send messages concurrently without any additional code. This is because the MDB pooling: the instances of MDB are stored inside a pool and when a message arrives to the queue, an instance is retrieved from the pool and used to send the message.
I am now going to show you how to create a consumer for the message just created with jms; in my MDB I get the email information of the UserBean I included into the message and I send him and email confirmation.With the @MessageDriven we identify this object as MDB and specify a MDB configuration including the fact that we are listening to the ConfirmMailQueue of the type javax.jms.Queue.
Then we mark our MDB as JMS listener by implementing the MessageListener interface.
The onMessage() method implements the message listener interface and processes the incoming message.
For cleaning purposes we only retrieve the ObjectMessage on the onMessage() method and we do our business on another method passing it the UserBean retrieved from the message.
The business method is the sendMessage() in which I create the connection to the mail server and after the authentication I prepare and send the email. I used a Singleton to prepare and start the connection to the mail server using parameters stored in a property file. Then I passed the session to the MimeMessage and created the message to be sent. In the code you can see that I set the recipient retrieved from the UserBean object, then I also used this object to retrieve his username used in the mail text.
Then I used the transport object to which I set the smtp protocol as connection type and after the authentication I sent the email.
Finally I closed the transport session in the finally clause of my try-catch.
The MDB as the Session Beans has a lifecycle; its lifecycle is equal to the stateless session bean with only two states: the Creation and the Destruction and as it we can use the same callback methods, annotated with the @PostConstruct and @PreDestroy metadata annotations.
Hi
ReplyDeleteVery useful topic
Can you please give a link to download this complete example so that it will be very useful
Hi, I no longer have the project, I am so sorry.
ReplyDeleteOK Thanks for the reply
ReplyDeleteRegards
Phani
Great work! Thanx :D
ReplyDeletenice example. thanks.........
ReplyDelete