Nel seguente esempio proviamo a :
- Definire una coda JMS su Jboss 5.1;
- Realizzare un programma client java che scriva sulla coda dei messaggi;
- Realizzare un Message Driven Bean che legga il messaggio e lo tolga dalla coda JMS.
DEFINIRE CODA JMS
Sotto la directory default deploy creare una directory denominata code dove andremo a definire la nostra coda JMS.
A questo punto dalla console di amministrazione di Jboss (utenza e pwd di default sono admin admin).
Cliccando su Add a new Resource e seguendo il menu definiamo il nome della coda "MiaCoda" e il JNDI name "code/MiaCoda".
Una volta terminata la procedura possiamo verificare il corretto funzionamento guardando sotto la directory deploy/code, troveremo il file xml MiaCoda-service.xml.
DEFINIRE CLIENT JAVA
Definiamo un semplice progetto Java su eclipse, inserendo nel classpath tutte le librerie presenti nella directory client di Jboss.
Il codice nel main del programma è il seguente:
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
public class MessageSender {
public static void main(String[] args) throws Exception{
ConnectionFactory connectionFactory;
Destination destination;
Properties p=new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
Context ctx=new InitialContext(p);
connectionFactory=(ConnectionFactory)ctx.lookup("/ConnectionFactory");
destination=(Queue)ctx.lookup("/code/MiaCoda");
System.out.println("La coda e la connessione sono stati recuperati");
Connection connection=null;
connection=connectionFactory.createConnection();
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer mp=session.createProducer(destination);
TextMessage msg = session.createTextMessage();
for (int i = 0; i < 5; i++) {
msg.setText("Questo è il messaggio " + (i + 1));
mp.send(msg);
}
connection.close();
System.out.println("Messaggi inviati correttamente");
}
}
Vengono scritti e inviati 5 messaggi.
Se proviamo ad eseguire il programma con Jboss acceso vediamo che da Console ci compare il seguente messaggio:
La coda e la connessione sono stati recuperati
Messaggi inviati correttamente
Quindi andando sulla console di amministrazione di Jboss in corrispondenza della coda "MiaCoda" troviamo:
Vediamo che risultano 0 consumer (nessuno ha letto i messaggi, non essendoci ancora l'MDB) e 5 messaggi presenti nella coda.
DEFINIRE IL MESSAGE DRIVEN BEAN
L' MDB ha il compito di connettersi alla coda e leggere i messaggi presenti.
Per realizzarlo creiamo un progetto Java inserendo nel classpath le librerie client di Jboss 5.1.
Per definire l'MDB annotiamo la classe con @MessageDriven, mentre la classe deve implementare l'interfaccia MessageListener (del package javax.jms).
Da notare la definizione dell'elemento activationConfig dove si specifica il tipo di Destination (in questo caso una coda) e il nome della coda ("code/MiaCoda").
Il codice è il seguente:
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(name="MessageBean",
activationConfig= {
@ActivationConfigProperty(propertyName="destinationType",
propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",
propertyValue="code/MiaCoda")
}
)
public class MessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdc;
public void onMessage(Message msg) {
TextMessage tmsg = null;
try
{
tmsg = (TextMessage) msg;
System.out.println("MESSAGE BEAN: Messaggio ricevuto: " + tmsg.getText( ));
System.out.println ("Metodo onMessage() richiamato");
}
catch (JMSException e) {
e.printStackTrace( );
mdc.setRollbackOnly( );
}
catch (Throwable th) {
th.printStackTrace();
}
}
}
Una volta fatto ciò possiamo esportare il progetto come jar file all'interno della directory deploy di JBoss.
Una volta deployato subito si nota sulla console di Jboss che i messaggi messi nella coda sono stati consumati dall'MDB:
13:06:53,945 INFO [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 2
13:06:53,945 INFO [STDOUT] Metodo onMessage() richiamato
13:06:53,946 INFO [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 3
13:06:53,946 INFO [STDOUT] Metodo onMessage() richiamato
13:06:53,947 INFO [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 1
13:06:53,947 INFO [STDOUT] Metodo onMessage() richiamato
13:06:53,947 INFO [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 4
13:06:53,948 INFO [STDOUT] Metodo onMessage() richiamato
13:06:53,949 INFO [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 5
13:06:53,950 INFO [STDOUT] Metodo onMessage() richiamato
Andando sulla coda via console di amministrazione vediamo infatti che adesso il Campo Consumer count è pari a 1 mentre il Message Count a 0.
Tutti i messaggi sono stati letti quindi dall'MDB e la coda è stata svuotata.
SCRIVERE MESSAGGI SULLA CODA JMS VIA WEB APPLICATION
In questo caso realizziamo una semplice Web appplication con un form su cui si inserisce il messaggio in una textArea e si invia il tutto ad una servlet che si occupa di aggiungere il messaggio alla coda jms.
Si noti come in questo caso i riferimenti alla ConnectionFactory e alla Destination siano recuperati tramite l'annotazione @Resource e non tramite look up JNDI.
public class ScriviMessaggioSuCoda extends HttpServlet {
private static final long serialVersionUID = 1L;
@Resource(name="code/MiaCoda",mappedName="code/MiaCoda")
private javax.jms.Destination codaTest;
@Resource(name="ConnectionFactory",mappedName="ConnectionFactory")
private javax.jms.ConnectionFactory connentionFactory;
/**
* @see HttpServlet#HttpServlet()
*/
public ScriviMessaggioSuCoda() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
try
{
String messaggio=request.getParameter("txtMessage");
Connection connection = connentionFactory.createConnection();
connection=connentionFactory.createConnection();
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer mp=session.createProducer(codaTest);
TextMessage msg = session.createTextMessage();
msg.setText(messaggio);
mp.send(msg);
connection.close();
System.out.println("Sending message");
session.close ();
PrintWriter wr=response.getWriter();
wr.write("<b>Messaggio inviato</b>");
wr.flush();
}
catch(Exception ex){
ex.printStackTrace();
}
}
}