Verwenden Sie diese Aufgabe, um eine JMS-Clientanwendung zu entwickeln, die über Nachrichten mit Unternehmensanwendungen kommuniziert.
Informationen zu diesem Vorgang
Dieser Abschnitt enthält eine Übersicht der Schritte, die zum Entwickeln einer JMS-Clientanwendung ausgeführt werden müssen.
In diesem Abschnitt werden nur JMS-spezifische Aspekte und keine allgemeine Clientprogrammierung beschrieben. Mit der allgemeinen Clientprogrammierung sollten Sie bereits vertraut sein.
Ausführliche Informationen zu diesen Schritten und
Beispiele für die Entwicklung von JMS-Clients finden Sie in der Dokumentation zu Java™ Message Service und im Abschnitt
Using Java des Information Center von IBM MQ.
Ein JMS-Client geht davon aus,
dass die JMS-Ressourcen (z. B. eine Warteschlangenverbindungsfactory und ein Warteschlangenziel) bereits vorhanden sind.
Eine Clientanwendung kann geeignete JMS-Ressourcen über eine JNDI-Suche oder programmgesteuert ohne JNDI
abrufen.
Informationen zu Thin Client for
JMS with WebSphere Application Server, einer integrierbaren Technologie, die
das Herstellen von JMS-Verbindungen der Version 1.1 zu einer Messaging-Engine des Standard-Messaging-Providers von WebSphere Application Server ermöglicht,
finden Sie unter JMS für die Herstellung von Verbindungen zu einer Messaging-Engine des Standard-Messaging-Providers von WebSphere Application Server verwenden.
Weitere Informationen zum Entwickeln von Clientanwendungen und zum Konfigurieren von JMS-Ressourcen für diese finden Sie unter
Code für J2EE Application Client entwickeln und unter den zugehörigen Tasks.
Zum Verwenden von JMS führt ein JMS-Standardclientprogramm
die folgenden allgemeinen Schritte aus. Dieses Beispiel basiert auf der Verwendung von JNDI-Suchen für das Abrufen von JMS-Ressourcen.
- JMS-Pakete importieren. Eine Unternehmensanwendung, die JMS verwendet, beginnt mit einer Reihe von Importanweisungen für JMS, z. B.:
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.jms.*;
- Ausgangskontext anfordern.
try {
ctx = new InitialContext(env);
...
- Parameter definieren, die der Client verwenden soll, um beispielsweise die Warteschlangenverbindungsfactory anzugeben und eine zu sendende Nachricht zu erstellen.
public class JMSppSampleClient
{
public static void main(String[] args)
throws JMSException, Exception
{
String messageID = null;
String outString = null;
String qcfName = "java:comp/env/jms/ConnectionFactory";
String qnameIn = "java:comp/env/jms/Q1";
String qnameOut = "java:comp/env/jms/Q2";
boolean verbose = false;
QueueSession session = null;
QueueConnection connection = null;
Context ctx = null;
QueueConnectionFactory qcf = null;
Queue inQueue = null;
Queue outQueue = null;
...
- Verwaltete Objekte aus dem JNDI-Namespace abrufen. Die Methode "InitialContext.lookup()" wird zum Abrufen verwalteter Objekte (Warteschlangenverbindungsfactory und Warteschlangenziele) verwendet:
qcf = (QueueConnectionFactory)ctx.lookup( qcfName );
...
inQueue = (Queue)ctx.lookup( qnameIn );
outQueue = (Queue)ctx.lookup( qnameOut );
...
- Verbindung zum Messaging-Service-Provider herstellen. Die Verbindung ermöglicht den Zugriff auf den zugrunde liegenden Transportmechanismus und wird für das Erstellen von
Sitzungen verwendet. Die Verbindung wird mit der Methode createQueueConnection() des Factory-Objekts erstellt.
connection = qcf.createQueueConnection();
Die JMS-Spezifikation legt fest, dass Verbindungen im Stoppstatus erstellt werden müssen. Bis zum Start der Verbindung
können die der Verbindung zugeordneten MessageConsumers keine Nachrichten empfangen. Setzen Sie zum Starten der Verbindung den
folgenden Befehl ab:
connection.start();
- Sitzung für das Senden und Empfangen von Nachrichten erstellen. Die Sitzung stellt einen Kontext für das Produzieren und Konsumieren von Nachrichten bereit, der auch die
Methoden für das Erstellen von MessageProducers und MessageConsumers beinhaltet. Zum Abrufen einer
Sitzung wird auf die Verbindung die Methode "createQueueSession" angewendet. Diese Methode verwendet zwei Parameter:
- Einen booleschen Wert, der festlegt, ob die Sitzung eine Transaktionssitzung ist.
- Einen Parameter, der den Bestätigungsmodus festlegt.
boolean transacted = false;
session = connection.createQueueSession( transacted,
Session.AUTO_ACKNOWLEDGE);
In diesem Beispiel ist die Sitzung keine Transaktionssitzung. Der Empfang von Nachrichten wird automatisch bestätigt. Bei Verwendung dieser Einstellungen wird eine
Nachricht nur zurückgesetzt, wenn ein Systemfehler auftritt oder die Clientanwendung unerwartet beendet wird.
- Nachricht senden.
- MessageProducers für das Erzeugen von Nachrichten erstellen. Für das Punkt-zu-Punkt-Messaging ist der MessageProducer ein QueueSender, der durch das Übergeben eines (zuvor abgerufenen) Ausgabewarteschlangenobjekts
an die Methode "createSender" in der Sitzung
erstellt wird. Ein QueueSender wird normalerweise für eine bestimmte Warteschlange erstellt, sodass alle
Nachrichten mit diesem Absender an dieselbe Zieladresse gesendet werden.
QueueSender queueSender = session.createSender(inQueue);
- Nachricht erstellen. Erstellen Sie in der Sitzung eine leere Nachricht, und fügen Sie die übergebenen Daten hinzu.
JMS
bietet mehrere Nachrichtentypen an, die jeweils gewisse Informationen zum Inhalt der Nachricht haben. Um die Referenz auf
lieferantenspezifische Klassennamen für die Nachrichtentypen zu vermeiden, werden dem Session-Objekt für Nachrichtenerstellung Methoden
zur Verfügung gestellt.
In diesem Beispiel wird eine Textnachricht aus der Eigenschaft
"outString" erstellt, die als Eingabeparameter beim Aufruf des Clientprogramms angegeben oder auf andere Weise erstellt werden kann:
TextMessage outMessage = session.createTextMessage(outString);
- Nachricht senden.
Zum Senden wird die Nachricht an die send-Methode des
QueueSender übergeben:
queueSender.send(outMessage);
- Antworten empfangen.
- Erstellen Sie die Korrelations-ID zur Verknüpfung der gesendeten Nachricht mit den Antworten. In diesem Beispiel kann der Client dank der providerspezifischen Nachrichten-ID in einer JMSCorrelationID
Antworten auf die von ihm gesendete Nachricht empfangen.
messageID = outMessage.getJMSMessageID();
Die
Korrelations-ID wird dann in einem Nachrichtenselektor verwendet, um nur Nachrichten mit dieser ID auszuwählen:
String selector = "JMSCorrelationID = '"+messageID+"'";
- Erstellen Sie einen MessageReceiver (Nachrichtenempfänger) für den Nachrichtenempfang. Für das Punkt-zu-Punkt-Messaging ist der MessageReceiver ein QueueReceiver, der durch das Übergeben
eines (zuvor abgerufenen) Eingabewarteschlangenobjekts und des Message Selector an die Methode
createReceiver der Sitzung erstellt wird.
QueueReceiver queueReceiver = session.createReceiver(outQueue, selector);
- Rufen Sie die Antwortnachricht ab. Für das Abrufen einer Antwort wird die receive-Methode des QueueReceiver
verwendet:
Message inMessage = queueReceiver.receive(2000);
Der Parameter im Aufruf von
receive ist ein Zeitlimit in Millisekunden. Dieser Parameter definiert, wie lange die Methode warten soll, falls nicht sofort
eine Nachricht verfügbar ist.
Wenn Sie diesen Parameter nicht verwenden, führt der Aufruf zu einer unbegrenzten Blockierung. Wenn Sie keine Verzögerung wünschen, verwenden
Sie die Methode
"receiveNoWait()". In diesem Beispiel kehrt der Aufruf von receive beim zuerst eintretenden der beiden folgenden Ereignisse zurück:
beim Eintreffen der Nachricht oder nach Ablauf von 2000 ms.
- Bearbeiten Sie die empfangene Nachricht. Wenn Nachrichten empfangen werden, können Sie mit diesen gemäß den Anforderungen der Geschäftslogik des Clients
verfahren. Zu den allgemeinen JMS-Aktionen gehört das Überprüfen des Nachrichtentyps und das Extrahieren des Nachrichteninhalts. Wenn Sie den
Inhalt aus dem Hauptteil der Nachricht extrahieren möchten, müssen Sie eine Umsetzung
von der generischen Message-Klasse (dem deklarierten Rückgabetyp der receive-Methoden)
in eine spezifischere Unterklasse vornehmen, z. B. auf
TextMessage. Sie sollten es sich zur Gewohnheit machen, vor der Umsetzung stets die Nachrichtenklasse zu testen, um bei unerwarteten
Fehlern gewappnet zu sein.
In diesem Beispiel wird mit dem Operator "instanceof" überprüft, ob die empfangene Nachricht eine
Nachricht des Typs "TextMessage" ist. Anschließend wird der Nachrichteninhalt durch Umsetzung in die Unterklasse
"TextMessage" extrahiert.
if ( inMessage instanceof TextMessage )
...
String replyString = ((TextMessage) inMessage).getText();
- Schließen. Wenn die Anwendung viele kurzlebige JMS-Objekte auf Sitzungsebene oder einer niedrigeren Ebene erstellen muss, ist es wichtig,
dass alle verwendeten JMS-Ressourcen geschlossen werden. Rufen Sie dazu für die verschiedenen Klassen
(QueueConnection, QueueSession, QueueSender und QueueReceiver) die Methode close() auf, wenn die Ressourcen nicht mehr benötigt
werden.
queueReceiver.close();
...
queueSender.close();
...
session.close();
session = null;
...
connection.close();
connection = null;
- Nachrichten veröffentlichen und subskribieren. Die allgemeinen Clientaktionen (z. B. zum Erstellen einer Sitzung und einer Verbindung) sind unabhängig davon, ob anstelle des Punkt-zu-Punkt-Messagings das Publish/Subscribe-Messaging verwendet werden soll,
identisch. Abweichend werden an Stelle von Warteschlangenressourcen Topicressourcen verwendet
(z. B. TopicPublisher an Stelle von QueueSender). Sehen Sie sich dazu das folgende Beispiel für das Publizieren einer
Nachricht an:
// TopicPublisher erstellen
TopicPublisher pub = session.createPublisher(topic);
...
pub.publish(outMessage);
...
// TopicPublisher schließen
pub.close();
- Fehler behandeln. JMS-Laufzeitfehler werden durch Ausnahmen gemeldet. Die Mehrzahl der Methoden löst in
JMS Ausnahmen des Typs "JMSException" aus, um Fehler anzuzeigen. Sie sollten es sich zur Gewohnheit werden lassen, diese Ausnahmen
abzufangen und in einer geeigneten Ausgabe anzuzeigen.
Im Gegensatz zu normalen
Java-Ausnahmen
kann eine JMSException weitere eingebettete Ausnahmen enthalten. Die Implementierung der JMSException
schließt die eingebettete Ausnahme nicht in die Ausgabe der
Methode "toString()" ein.
Sie müssen daher explizit prüfen, ob eine eingebettete Ausnahme vorhanden ist, und diese
dann wie im folgenden Beispiel gezeigt ausgeben:
catch (JMSException je)
{
System.out.println("JMS gescheitert mit "+je);
Exception le = je.getLinkedException();
if (le != null)
{
System.out.println("Verknüpfte Ausnahme "+le);
}
}
Nächste Schritte
Informationen zum Ausführen eines Clients auf einem bestimmten fernen Server finden Sie unter
Java EE-Clientanwendung mit launchClient ausführen.