java 實現jms的客戶端(發送接收消息)

本文以ActiveMQ 消息服務器中間件爲例。

實現的步驟如下:

1)實例化連接 工廠ConnectionFactory,主要設置的參數爲連接到消息服務器中間件的用戶名,密碼及url.

2)通過連接工廠ConnectionFactory獲取到消息中間件的連接Connection.

3)啓動連接,並創建消息會話Session,用於發送或接收消息的線程

4)通過消息會話創建消息目的地Destination

5)創建消息生產者MessageProducer或消息消費者MessageConsumer

6)通過消息生產者MessageProducer發送消息或通過消息消費者MessageConsumer接收消息

7)關閉並釋放連接資料

具體的實現代碼如下:

發送消息客戶端代碼如下:



import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

import com.afmobi.jms.model.User;

public class QueueSender {
	
	private ConnectionFactory connFactory;
	private Connection conn;
	private Session session;
	private MessageProducer producer;
	private boolean stop=false;

	public void execute() throws Exception {
		// 連接工廠
		// 設置用戶名和密碼,這個用戶名和密碼在conf目錄下的credentials.properties文件中
		connFactory = new ActiveMQConnectionFactory(
				ActiveMQConnection.DEFAULT_USER,
				ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
		// 連接到JMS提供者
		conn = connFactory.createConnection();
		conn.start();

		// 事務性會話,自動確認消息
		// 第一個參數是否使用事務:當消息發送者向消息提供者(即消息代理)發送消息時,消息發送者等待消息代理的確認,沒有迴應則拋出異常,消息發送程序負責處理這個錯誤。
		// 第二個參數消息的確認模式:
		// AUTO_ACKNOWLEDGE :
		// 指定消息提供者在每次收到消息時自動發送確認。消息只向目標發送一次,但傳輸過程中可能因爲錯誤而丟失消息。
		// CLIENT_ACKNOWLEDGE :
		// 由消息接收者確認收到消息,通過調用消息的acknowledge()方法(會通知消息提供者收到了消息)
		// DUPS_OK_ACKNOWLEDGE : 指定消息提供者在消息接收者沒有確認發送時重新發送消息(這種確認模式不在乎接收者收到重複的消息)
		session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);

		// 創建目標,就創建主題也可以創建隊列
		Destination destination = session.createQueue("queue.hello");

		// 消息生產者
		producer = session.createProducer(destination);
		// 設置持久化,DeliveryMode.PERSISTENT和DeliveryMode.NON_PERSISTENT
		// 如果DeliveryMode沒有設置或者設置爲NON_PERSISTENT,那麼重啓MQ之後消息就會丟失。
		producer.setDeliveryMode(DeliveryMode.PERSISTENT);// 持久化

		// 發送消息
		while(!stop){
			Thread.sleep(1000);
			sendObject(session, producer);
			session.commit();// 在事務會話中,只有commit之後,消息纔會真正到達目的地
			System.out.println("已發送消息");
			
		} 
		

		
		producer.close();
		session.close();
		conn.close();
	}

	// 對象消息
	public void sendObject(Session session, MessageProducer producer)
			throws JMSException {
		User user = new User();
		user.setAccount("petty");
		user.setName("happy");
		ObjectMessage objectMessage = session.createObjectMessage();
		objectMessage.setObject(user);
		producer.send(objectMessage);
	}

	// 字節消息
	public void sendBytes(Session session, MessageProducer producer)
			throws JMSException {
		String s = "BytesMessage字節消息";
		BytesMessage bytesMessage = session.createBytesMessage();
		bytesMessage.writeBytes(s.getBytes());
		producer.send(bytesMessage);
	}

	// 流消息
	public void sendStream(Session session, MessageProducer producer)
			throws JMSException {
		StreamMessage streamMessage = session.createStreamMessage();
		streamMessage.writeString("streamMessage流消息");
		streamMessage.writeLong(55);
		producer.send(streamMessage);
	}

	// 鍵值對消息
	public void sendMap(Session session, MessageProducer producer)
			throws JMSException {
		MapMessage mapMessage = session.createMapMessage();
		mapMessage.setLong("age", 25);
		mapMessage.setDouble("sarray", new Double(6555.5));
		mapMessage.setString("username", "鍵值對消息");
		producer.send(mapMessage);
	}

	// 文本消息
	public void sendText(Session session, MessageProducer producer)
			throws JMSException {
		TextMessage textMessage = session.createTextMessage("文本消息");
		producer.send(textMessage);
	}


}


接收消息客戶端代碼如下:



import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

import com.afmobi.jms.model.User;

public class QueueReceiver implements MessageListener{
	
	private ConnectionFactory connFactory;
	private Connection conn;
	private Session session;
	private boolean stop=false;
	
	public void execute()throws Exception{
		//連接工廠
		// 設置用戶名和密碼,這個用戶名和密碼在conf目錄下的credentials.properties文件中
		connFactory=new ActiveMQConnectionFactory(
				ActiveMQConnection.DEFAULT_USER,
				ActiveMQConnection.DEFAULT_PASSWORD,
				"tcp://localhost:61616");
		
		//連接到JMS提供者
		conn=connFactory.createConnection();
		conn.start();
		
		//事務性會話,自動確認消息
		// 第一個參數是否使用事務:當消息發送者向消息提供者(即消息代理)發送消息時,消息發送者等待消息代理的確認,沒有迴應則拋出異常,消息發送程序負責處理這個錯誤。
        // 第二個參數消息的確認模式:
        // AUTO_ACKNOWLEDGE : 指定消息提供者在每次收到消息時自動發送確認。消息只向目標發送一次,但傳輸過程中可能因爲錯誤而丟失消息。
        // CLIENT_ACKNOWLEDGE : 由消息接收者確認收到消息,通過調用消息的acknowledge()方法(會通知消息提供者收到了消息)
        // DUPS_OK_ACKNOWLEDGE : 指定消息提供者在消息接收者沒有確認發送時重新發送消息(這種確認模式不在乎接收者收到重複的消息)
		session=conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
		
		// 創建目標,就創建主題也可以創建隊列
		Destination destination=session.createQueue("queue.hello");
		
		//消息的消費者
		MessageConsumer consumer=session.createConsumer(destination);
		consumer.setMessageListener(this);
		
		//等待接收消息
		while(!stop){
			Thread.sleep(5000);
		}
				
		consumer.close();
		session.close();
		conn.close();
	}

	public void onMessage(Message m) {
		try{
			if(m instanceof TextMessage){//接收文件消息
				TextMessage message=(TextMessage)m;
				System.out.println(message.getText());
			}else if(m instanceof MapMessage){//接收鍵值消息
				MapMessage message=(MapMessage)m;
				System.out.println(message.getLong("age"));
				System.out.println(message.getDouble("sarray"));
				System.out.println(message.getString("username"));
			}else if(m instanceof StreamMessage){//接收流消息
				StreamMessage message=(StreamMessage)m;
				System.out.println(message.readString());
				System.out.println(message.readLong());
			}else if(m instanceof BytesMessage){
				byte[] b=new byte[1024];
				int len=-1;
				BytesMessage message=(BytesMessage)m;
				while((len=message.readBytes(b))!=-1){
					System.out.println(new String(b,0,len));
				}
			}else if(m instanceof ObjectMessage){
				ObjectMessage message=(ObjectMessage)m;
				User user=(User)message.getObject();
				System.out.println("name:"+user.getAccount()+";info:"+user.getName());
			}else{
				System.out.println(m);
			}
			session.commit();
		}catch(JMSException e){
			e.printStackTrace();
		}
		
		
	}

}


以上代碼是PTP即點對點消息模式的示例,如果採用Sub/Pub即發佈/訂閱者消息模式,基本代碼的實現過程都一樣,只需把

創建消息目的地的代碼
Destination destination = session.createQueue("queue.hello");

修改爲

Destination destination=session.createTopic("topic.hello");

即可。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章