使用JMS接口接入WebSphere MQ消息

在你的應用程序中利用IBM WebSphere MQ消息中間件提供Java消息服務開放接口。html

  IBM WebSphere MQ(WMQ)是一套面向消息的中間件(message-oriented middleware,MOM),經過使用消息和隊列簡化應用程序之間的通訊,WMQ支持點到點的和發佈/訂閱消息,支持多種平臺,包括Windows、AIX、HP-UX和Sun Solaris,它特別適合目前的異構計算環境。java

  對於Java開發者而言,WMQ爲Java應用程序提供了兩種接口:windows

  1.爲Java提供MQ基礎類 - 一個基於WMQ本地接口的Java接口。session

  2.MQ JMS - Java消息服務(Java Messaging Service ,JMS)1.1接口的實現。app

  JMS經過開啓Java應用程序發送和接收消息擴展了Java的互操做性,JMS應用程序可使用點到點或發佈/訂閱模式進行消息交換。工具

  本文描述的是使用WMQ和JMS進行開發的過程,重心集中在點到點消息,經過下面幾步教你如何使用Java類編寫JMS接口:性能

  1.建立WMQ對象測試

  2.建立JMS管理對象ui

  3.解釋JMS代碼url

  4.運行一個實例類發送消息和從WMQ接收消息

  WMQ安裝

  本文使用的是winxp上的MQ 版本 7(能夠從http://www.ibm.com/developerworks/downloads/ws/wmq/learn.html下載試用版),在windows上的安裝是很是簡單的,一路默認就能夠完成安裝。

  若是你尚未使用過WMQ也不要擔憂,你可使用基於Eclipse的WebSphere MQ管理器,它是一個簡單的用於管理WMQ的圖形工具。

  建立MQ對象:隊列管理器和隊列

  隊列是用來存儲消息的,直到應用程序處理完畢才釋放,隊列管理器擁有並管理隊列,要建立一個隊列管理器和隊列,按如下步驟啓動WebSphere MQ管理器:開始?全部程序? IBM WebSphere MQ ? WebSphere MQ Explorer。圖1顯示了啓動WebSphere MQ管理器時的樣子。

  圖1 WebSphere MQ 管理器

  在MQ管理器中執行下列操做建立一個隊列管理器:

  1.在導航視圖下,右擊「隊列管理器」,選擇「新建--隊列管理器」,啓動建立隊列管理器嚮導。

  2.在第一步中輸入隊列管理器的名字「TestMQ」,點擊「下一步」。如圖2所示。

  圖2 建立隊列管理器,第一步:輸入隊列管理器名稱

  3.在第二步和第三步都點擊「下一步」,進入第四步,肯定選中了「建立一個TCP/IP監聽器」,而後輸入一個未使用的端口號,點擊「完成」。如圖3所示。

  圖3 建立隊列管理器,第四步:檢查隊列管理器的監聽器端口號。

  接下來建立兩個隊列:IN.QUEUE 和 OUT.QUEUE。你就能夠將消息寫入IN.QUEUE,從OUT.QUEUE讀取消息。

  1.在TestMQ下,右擊「隊列」?「新建」?「本地隊列」啓動「新建本地隊列」嚮導。

  2.在名稱區域,輸入IN.QUEUE,點擊「完成」。如圖4所示。

  圖4 建立隊列嚮導:輸入隊列名稱,其它屬性值保留默認值

  3.重複上面的步驟建立好隊列OUT.QUEUE。

建立JMS管理對象

  JMS定義了一個通用的接口來發送和接收消息,只要與之通訊的程序兼容JMS便可,點到點的JMS接口是:

  1. javax.jms.QueueConnection - 這個接口提供一個到JMS提供程序的鏈接,用於建立會話對象。

  2.javax.jms.QueueSession - 這個接口爲產生和消耗消息提供上下文呢,包括建立QueueSender和QueueReceiver的方法。

  3. javax.jms.QueueSender - 這個接口用於向隊列發送消息,javax.jms.QueueReceiver用於從隊列接收消息。

  爲了讓你的代碼能夠在不一樣的消息提供程序間有良好的移植性,你必須在你的應用程序中使用javax.jms中的標準JMS接口,全部特定廠家的信息都封裝在javax.jms.QueueConnectionFactory 和 javax.jms.Queue中,這些管理對象可使用廠家提供管理工具進行構建,存儲在JNDI命名空間中,JMS應用程序能夠從命名空間中檢索這些對象,這時就不須要知道是哪一個廠家提供的了。

  按照下面的步驟使用Websphere MQ管理器建立管理對象,存儲在基於文件的目錄下:

  1.在JMS-管理對象上點擊右鍵?添加初始上下文。

  2.在屏幕1上:

   爲「JNDI存儲在哪裏」選擇「文件系統」

   在關聯目錄處,輸入C:\JNDI-Directory(前提是這個目錄已經存在)

   注意工廠類和提供程序URL,由於你將會在Java代碼中使用到(如圖5所示)

  圖5 添加初始上下文嚮導:你將在樣例類中使用工廠類和提供程序URL

  3.你的管理器如今應該如圖6所示

  圖6 添加初始上下文後的MQ管理器:你能夠在MQ管理器中輕易地建立JMS管理對象

  在新的初始上下文中,建立一個鏈接工廠。

  1.在鏈接工廠上點擊右鍵?新建?鏈接工廠,在第一個屏幕上,在名稱區域輸入「TestQM_QCF」,點擊「下一步」,在JNDI查找中你就使用TestQM_QCF了。

  2.將類型設置爲「隊列鏈接工廠」,點擊「下一步」。如圖7所示。

  圖7 新建鏈接工廠嚮導:用於點對點消息的隊列鏈接工廠

  3.保持傳送類型爲聚集,點擊下一步,當WMQ和應用程序在同一機器上時使用聚集傳輸。

  4.在下一頁面點擊下一步(無需修改設置)。

  5.在最後一頁,選擇鏈接標籤,點擊「選擇」按鈕選擇TestQM做爲「基礎隊列管理器」。如圖8所示。

  圖8 新建鏈接工廠嚮導:鏈接工廠被包裝爲TestMQ

  6.點擊「完成」。

  接下來建立目的地,對應WMQ消息的JMS管理對象。

  1.在目的地上點擊右鍵?選擇「新建」?「目的地」。

  2.在第一頁上,在名字區域輸入INInputTestQueue做爲名字,確保類型設置爲隊列了,點擊「下一步」。如圖9所示。

  圖9 新建目的地嚮導:使用InputTestQueue查找IN.QUEUE

  3.第二頁保持默認設置不變,點擊「下一步」。

  4.在最後一頁:

   在隊列管理器區域,點擊「選擇」按鈕選擇TestQM。

   在隊列區域,點擊「選擇」按鈕選擇IN.QUEUE。

  5.點擊「完成」。

  重複上述步驟建立另外一個目的地:OutputTestQueue,它對應OUT.QUEUE

理解示例類

  若是你編寫過JMS應用程序,就很容易理解JNDIUtil 和 Tester示例類(從http://assets.devx.com/sourcecode/WebSphereMQ_JMSSource&Classes.zip下載Java源文件和編譯好的類),你建立的JMS管理對象隱藏了全部廠家專利實現。

  JNDIUtil類

  JNDIUtil包括使用名字經過JNDI查找檢索對象的方法,參考清單1,你可使用這個類中的方法檢索你在MQ管理器中定義的JMS對象的引用狀況。

  清單1 JNDIUtil.java

package devx.articles.mqjms;
  
// JMS 類    import javax.jms.JMSException;
  
import javax.jms.Queue;
  
import javax.jms.QueueConnectionFactory;
  
// JNDI 類    import javax.naming.InitialContext;
  
import javax.naming.Context;
  
import javax.naming.NamingException;
  
// 標準 Java類    import java.util.Hashtable;
  
/**
  *
  * A wrapper class for JNDI calls
  *
  
*/
  
public class JNDIUtil
  {
  
private Context context;
  
public JNDIUtil(String icf, String url) throws JMSException, NamingException
  {
  Hashtable environment
= new Hashtable();
  environment.put(Context.INITIAL_CONTEXT_FACTORY, icf );
  environment.put(Context.PROVIDER_URL, url);
  context
= new InitialContext( environment );
  }
  
/**
  *
  *
@param ObjName Object Name to be retrieved
  *
@return Retrieved Object
  *
@throws NamingException
  
*/
  
private Object getObjectByName(String ObjName) throws NamingException
  {
  
return context.lookup( ObjName );
  }
  
/**
  * A convenience method that returns QueueConnectionFactory objects (no casting required)
  *
@param factoryName QueueConnectionFactory JNDI name
  *
@return QueueConnectionFactory object
  *
@throws NamingException
  
*/
  
public QueueConnectionFactory getQueueConnectionFactory(String factoryName) throws NamingException
  {
  
return (QueueConnectionFactory) getObjectByName(factoryName);
  }
  
/**
  * A convenience method that returns Queue objects (no casting required)
  *
@param queueName
  *
@return
  *
@throws NamingException
  
*/
  
public Queue getQueue(String queueName) throws NamingException
  {
  
return (Queue) getObjectByName(queueName);
  }
  }

    Tester類

  Tester類向OUT.QUEUE中寫入消息,從IN.QUEUE中讀取消息。參考清單2.

  清單2 Tester.java

  package devx.articles.mqjms;
  
// JMS 類    import javax.jms.Queue;
  
import javax.jms.QueueSession;
  
import javax.jms.QueueConnection;
  
import javax.jms.QueueConnectionFactory;
  
import javax.jms.JMSException;
  
import javax.jms.Session;
  
import javax.jms.QueueSender;
  
import javax.jms.QueueReceiver;
  
import javax.jms.TextMessage;
  
import javax.jms.Message;
  
// JNDI 類    import javax.naming.NamingException;
  
// 標準 Java 類    /**
  *
  * A class to test JMS with IBM MQ
  *
  
*/
  
public class Tester
  {
  
public static String icf = " com.sun.jndi.fscontext.RefFSContextFactory " ;
  
public static String url = " file:/C:/JNDI-Directory " ;
  
public static void main(String[] vars) throws JMSException, NamingException
  {
  QueueSession session
= null ;
  QueueConnection connection
= null ;
  QueueConnectionFactory factory
= null ;
  QueueSender queueSender
= null ;
  QueueReceiver queueReceiver
= null ;
  Queue oQueue
= null ; // 消息發送到的隊列   Queue iQueue = null ; // 接收消息的隊列    try
  {
  JNDIUtil jndiUtil
= new JNDIUtil(icf,url);
  factory
= jndiUtil.getQueueConnectionFactory( " TestQM_QCF " );
  connection
= factory.createQueueConnection();
  
// 啓動(或從新啓動)入站消息的鏈接地址,若是沒有這個調用消息不會被接收   connection.start();
  
// 表示一個非相互操做會話    boolean transacted = false ;
  session
= connection.createQueueSession( transacted, Session.AUTO_ACKNOWLEDGE);
  oQueue
= jndiUtil.getQueue( " OutputTestQueue " );
  queueSender
= session.createSender(oQueue);
  TextMessage oMsg
= session.createTextMessage();
  oMsg.setText(
" www.devx.com " );
  
// 你還能夠設置其餘消息屬性   queueSender.send(oMsg);
  iQueue
= jndiUtil.getQueue( " InputTestQueue " );
  queueReceiver
= session.createReceiver(iQueue);
  Message iMsg
= queueReceiver.receive( 1000 );
  
if ( iMsg != null )
  System.out.println( ((TextMessage)iMsg).getText() );
  
else
  System.out.println(
" No messages in queue " );
  }
  
finally
  {
  
// 老是釋放資源    if ( queueReceiver != null )
  queueReceiver.close();
  
if ( queueSender != null )
  queueSender.close();
  
if ( session != null )
  session.close();
  
if ( connection != null )
  {
  connection.close();
  }
  }
  }
  }

   開始點是鏈接工廠查找,這個工廠用於建立一個鏈接:

factory = jndiUtil.getQueueConnectionFactory( " TestQM_QCF " );
  connection
= factory.createQueueConnection();

   鏈接對象用於建立一個會話:

 session = connection.createQueueSession( transacted, Session.AUTO_ACKNOWLEDGE);

  要將消息寫入IN.QUEUE queue,查找前面建立的目的地對象OutputTestQueue:

oQueue = jndiUtil.getQueue( " OutputTestQueue " );

  最後建立一個QueueSender對象將消息寫入隊列:

queueSender = session.createSender(oQueue); TextMessage oMsg = session.createTextMessage(); oMsg.setText( " www.devx.com " ); queueSender.send(oMsg);

  從OUT.QUEUE讀取消息的過程相同,但使用的是QueueReceiver。

編譯運行示例類

  當你安裝WMQ時會自動將編譯和運行示例類須要的jar文件添加到CLASSPATH環境變量中,須要的jar文件位於C:\Program Files\IBM\WebSphere MQ\Java\lib,包括JMS和JNDI須要的jar。

  在運行Tester類以前,使用MQ管理器向IN.QUEUE增長一條測試消息:

  1.在 IN.QUEUE上點擊右鍵,選擇放入測試消息。

  2.輸入任意文本,點擊放入消息。

  若是你尚未在IN.QUEUE隊列中放入過消息,Tester類會顯示「隊列中無消息」。

  要運行Tester類,將Tester.class 和 JNDIUtil.class添加到CLASSPATH,而後在命令提示符輸入:

 java devx.articles.mqjms.Tester

   應用程序向OUT.QUEUE寫入一條消息,並顯示從IN.QUEUE檢索到的消息,要檢查發送到OUT.QUEUE中的消息,進入MQ管理器,在OUT.QUEUE上點擊右鍵?選擇「瀏覽消息」便可。

  企業中的Java和WMQ MOM

  在大型企業環境下,能夠充分利用WMQ的性能和穩定性優點,只要你的代碼遵循Java標準接口,你就能夠受益。

相關文章
相關標籤/搜索