消息傳遞系統通常被成為MOM(Message Oriented MiddleWare),作為消息服務器,MOM需要客戶端用統一的標准訪問服務器,JMS標准是使用
最廣泛的消息接口標准.
JMS消息分點對點、基於主題的消息兩種
點對點方式:是兩個客戶端建立消息隊列,消息發送者(sender)把消息(Message)給消息服務器中的一個隊列(Queue),消息接受者(receiver)從服務器中這個隊列中
獲取消息.
主題消息:消息發送者響向消息服務器中的一個主題發送消息(Message),對這個消息有訂閱的接受者都會接受到這個消息.
JMS中的主要名詞:
1)目的地(Desination)
是發送者和接受者的一個共同的地點,發送者把消息發送到這裡,接受者從這裡獲取消息,是我們在服務器中創建的一個隊列,服務器會對這個地方的所有消息維護。
2)會話
消息發送者和接受,都要通過JNDI獲取消息服務器的上下文,session就是這樣的一個上下文對象,它可以創建消息生產者、消費者,可以創建點對點消息、主題消息
所有的消息操作都圍繞這個會話展開.
消息結構的介紹
用過web services(SOAP)應該知道消息包括信封、消息頭、主體、附件.同樣JMS消息結構也是差不多包括消息頭、消息屬性、消息體.
以JMS、SOAP為基礎可以實現面向消息模型(MOM Message Oriented Model)。
JMS消息樣式:
SpyTextMessage {
Header {
jmsDestination : QUEUE.mytestjms
jmsDeliveryMode : 2
jmsExpiration : 0
jmsPriority : 4
jmsMessageID : ID:6-11454947326091
jmsTimeStamp : 1145494732609
jmsCorrelationID: null
jmsReplyTo : null
jmsType : null
jmsRedelivered : false
jmsProperties : {}
jmsPropReadWrite: false
msgReadOnly : true
producerClientId: ID:6
}
Body {
text :sender message from liao test
}
JMS簡單編程實現點對點的消息 服務器用jboss-4.0.3SP1
1)首先在JBOSS中部屬一個點對點的消息隊列
配置文件放在JBOSS_Home\server\default\deploy\jms
配置文件的內容為:
<?xml version="1.0" encoding="UTF-8"?>
<server>
<!--是一個點對點的用org.jboss.mq.server.jmx.Queue(Topic),desination的名稱為mytestjms
更多的配置說明可以看原來jboss自帶的Jms配置文件,文件名要用*-service.xml
-->
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=mytestjms">
<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>
</server>
2)實現消息發送者
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.*;
public class JMSSender {
QueueSession session;
QueueConnection conn;
QueueSender sender;
QueueReceiver receiver;
public void clientconnect()throws Exception
{
//消息服務器(destination)設置
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL,"localhost");
Context iniCtx = new InitialContext(env) ;
//查找創建JMS連接的工廠類
Object tmp = iniCtx.lookup("ConnectionFactory");
QueueConnectionFactory qcf = (QueueConnectionFactory)tmp;
//查找JMS目標對象 點對點
Queue queue = (Queue)iniCtx.lookup("queue/mytestjms");
//創建JMS連接
conn = qcf.createQueueConnection();
//創建JMS會話
session = conn.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
//開始連接
conn.start();
sender = session.createSender(queue);
receiver = session.createReceiver(queue);
}
public JMSSender()
{
try{
System.out.println("begin");
clientconnect();
TextMessage textmsg = this.session.createTextMessage();
textmsg.setText("sender message from liao test");
//發送消息 點對點
sender.send(textmsg);
disConnect();
System.out.println("success");
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 停止和關閉JMS連接
* @throws JMSException
*/
public void disConnect() throws JMSException
{
conn.stop();
session.close();
conn.close();
}
public Message receiver() throws JMSException
{
return receiver.receive(1000);
}
public static void main(String[] args)throws Exception
{
new JMSSender();
}
}
3)實現消息接受者
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.*;
public class JMSReceiver {
QueueSession session;
QueueConnection conn;
QueueReceiver receiver;
public void clientconnect()throws Exception
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL,"localhost");
Context iniCtx = new InitialContext(env) ;
Object tmp = iniCtx.lookup("ConnectionFactory");
QueueConnectionFactory qcf = (QueueConnectionFactory)tmp;
Queue queue = (Queue)iniCtx.lookup("queue/mytestjms");
conn = qcf.createQueueConnection();
session = conn.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
conn.start();
receiver = session.createReceiver(queue);
}
public void disConnect() throws JMSException
{
conn.stop();
session.close();
conn.close();
}
public Message receiver() throws JMSException
{
return receiver.receive(1000);
}
public JMSReceiver()throws Exception
{
clientconnect();
Message msg = receiver();
System.out.println(msg);
if (msg instanceof TextMessage)
{
TextMessage tmsg = (TextMessage)msg;
//消息主題內容:
System.out.println(tmsg.getText());
}
System.out.println("success");
disConnect();
}
public static void main(String[] args)throws Exception
{
new JMSReceiver();
}
}
主題消息用到Topic,思路基本相同,接受必需先訂閱消息主題,當有發送者把消息發給這個主題的時候
先前訂閱的接受就會收到這個消息。
SOA中JMS也是一個熱門,客戶端通常用JMS發送消息再ESB中調用具體的服務。