Working with messages involves the interaction between system components through message passing. JMS allows you to implement this interaction in a java application, and MDB beans allow you to asynchronously process the received messages on the application server without additional asynchronous processing efforts.
Below is a simple example of handling a JMS message using MDB.
Some theory
Auxiliary software, usually included in the application server package, is used to work with messages.
System components can send messages (producer) and receive messages (consumer). Message
sends the producer to the destination, which is on the queue or topic server, after which the consumer can pick up a message from there
Depending on what type the destination has, they separate the two message handling models.
')
The first model - Point-to-Point
If the destination server is of the queue type, the only consumer receives the message that the producer sent. If there are several recipients subscribed to this message queue, then only one of them will receive the message.
The second model is Publish-subscribe
If the destination server has a type of topic, then one message can be read by an unlimited number of consumers subscribed to this destination.
JMS message structure
A message consists of a header, a property field and a body.
The header stores the meta information of the message that is automatically filled.
The properties field is similar to the title, but it is filled programmatically, and the recipient can later read this information.
The body contains the message payload. The type of load is determined when creating the message. Specific types inherited from the
javax.jms.Message interface
Creating a queue on the server.
For example, create a topic on the server. I will use glassfish 3.1.
First, create a Connection Factory. Several types are possible depending on what type of message queue will be used.

Then create a destination with a type indication.

Creating a message sender
In this case, the producer will be on the application server. If you need to send messages from a separate client, then you will need to get access to the objects in the standard way by their JNDI name from the context.
// @Resource(name="jms/TutorialPool") private ConnectionFactory connectionFactory; @Resource(name="jms/TutorialTopic") private Destination destination; public String getEnterString() { return enterString; } public void sendString(String enterString) { try { // Connection connection = connectionFactory.createConnection(); Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(destination); TextMessage message = session.createTextMessage(); // JMS message.setStringProperty("clientType", "web clien"); // payload message.setText(enterString); // producer.send(message); System.out.println("message sent"); // session.close(); connection.close(); } catch (JMSException ex) { System.err.println("Sending message error"); ex.printStackTrace(); } }
Message-driven bean
We will use MDB to process incoming messages on the server.
Messages could be received and processed with the help of pojo acting as a consumer. But using MDB will allow parallel processing of messages, without worrying about the complexity of asynchronous processing and additional code for subscribing to the message queue.
Asynchronous processing is implemented through a pool of objects, from which the server will select objects for processing a message if necessary.
To implement MBD, it suffices to inherit the bean from the javax.jms.MessageListener interface, implementing the onMessage () method, and annotate the class accordingly.
Let's make an example of MDB, which displays information about the incoming message to the server console.
@MessageDriven( // topic, mappedName="jms/TutorialTopic", name = "ExampleMDB") public class MDBExample implements MessageListener{ //, @Override public void onMessage(Message msg) { try { TextMessage message = (TextMessage)msg; // , consumer System.out.println("FROM MDB - client type IS " + message.getStringProperty("clientType")); // System.out.println("FROM MDB - payload IS" + message.getText()); } catch (JMSException ex) { ex.printStackTrace(); } } }
The required business logic is added to the onMessage method, depending on the type of message, its content, and so on.
If necessary, you can create a handler for manual processing of messages.
For example:
@Resource(name="jms/TutorialPool") private ConnectionFactory connectionFactory; @Resource(name="jms/TutorialTopic") private Destination destination; void onMessage(){ try { Connection connection = connectionFactory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer consumer = session.createConsumer(destination); connection.start(); while(true){ Message msg = consumer.receive(); // } // connection } catch (JMSException ex) { ex.printStackTrace(); } }
For a more detailed study of JMS and EJB in general, I can recommend books:
EJB 3 in Action - Debu Panda, Reza Rahman, Derek LaneA couple of books from Adam Bien