2013-10-23 109 views
1

我使用ActiveMQ 5.9.0發送和接收JMS。 首先我在隊列中發送MapMessage消息:ActiveMQ MapMessage接收消息與空表

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); 

Connection connection = connectionFactory.createConnection(); 
connection.start(); 

Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); 
Destination destination = session.createQueue("my-queue"); 

MessageProducer producer = session.createProducer(destination); 
MapMessage message = session.createMapMessage(); 
message.setDouble(key, value); 
producer.send(message); 
session.commit(); 
session.close(); 
connection.close(); 
System.out.println(message); 

什麼它打印出是:

ActiveMQMapMessage {commandId = 0,responseRequired =假,MESSAGEID = ID:LT006632-52708-1382520875674-11: 1:1:1:1,originalDestination = null,originalTransactionId = null,producerId = null,destination = queue:// my-queue,transactionId = TX:ID:LT006632-52708-1382520875674-11:1:1,expiration = 0,timestamp = 1382520891291,arrival = 0,brokerInTime = 0,brokerOutTime = 0,correlationId = null,replyTo = null,persistent = true,type = null,priority = 4,groupID = null,groupSequence = 0,targetConsumerId = null,compressed = false,userID = null,content = [email protected],marshalledProperties = null,dataStructure = null,redeliveryCounter = 0,size = 0,properties = null,readOnlyProperties = false,readOnlyBody =假,可投放=假,jmsXGroupFirstForConsumer = FALSE} ActiveMQMapMessage {theTable = {條目6 = 922.0}}

具有正確theTable在消息。

它接收消息中另一個項目以這種方式:

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); 

Connection connection = connectionFactory.createConnection(); 
connection.start(); 

final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); 
Destination destination = session.createQueue("my-queue"); 

MessageConsumer consumer = session.createConsumer(destination); 

consumer.setMessageListener(new MessageListener() { 

    public void onMessage(Message msg) { 
     MapMessage message = (MapMessage) msg; 
     // TODO something.... 
     try { 
      System.out.println(message.getJMSType()); 
      session.commit(); 
     } catch (JMSException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

}); 
Thread.sleep(30000); 

session.close(); 
connection.close(); 

但在接收消息它打印出:

ActiveMQMapMessage {commandId = 6,responseRequired =假,MESSAGEID = ID: LT006632-52708-1382520875674-11:1:1:1:1,originalDestination = null,originalTransactionId = null,producerId = ID:LT006632-52708-1382520875674-11:1:1:1,destination = queue:// my-隊列,transactionId = TX:ID:LT006632-52708-1382520875674-11:1:1,到期= 0,時間戳= 1382520891291,到達= 0,brokerIn time = 1382520891291,brokerOutTime = 1382520891298,correlationId = null,replyTo = null,persistent = true,type = null,priority = 4,groupID = null,groupSequence = 0,targetConsumerId = null,compressed = false,userID = null,content = [email protected],marshalledProperties = null,dataStructure = null,redeliveryCounter = 0,size = 0,properties = null,readOnlyProperties = true,readOnlyBody = true,droppable = false,jmsXGroupFirstForConsumer = false} ActiveMQMapMessage { theTable = {}}

使用空的theTable項目。 我想知道它是什麼原因以及如何解決這個問題。謝謝!

回答

3

我們使用ActiveMQ 5.8.0,但有相同的「問題」:接收後的日誌消息不會打印出'theTable'條目。

但解析地圖信息並再次登錄後,它會打印'theTable'條目!

看來你不知何故必須'觸摸'該消息或訪問其內容來打印'theTable'條目。這至少對我們有用。

+0

這工作!但它是如此奇怪...... – wceo

+1

是的,奇怪的行爲。您可以在ActiveMQ JIRA上編寫更改請求:https://issues.apache.org/jira/browse/AMQ ;-) – Mayoares

3

以上答案正確。我會詳細說明爲什麼它以這種方式工作。

MapMessage映射(theMap)的內容被編組爲一個更小的二進制形式進行傳輸,甚至可以根據OpenWire協議的設置進行壓縮。當地圖元素被訪問時,地圖值只是懶散地解組,這就是爲什麼日誌語句不會在接收端顯示它們的原因。做這件事有很多原因。

在代理端,你真的不希望花費大量的時間記錄所有地圖元素只是有一些簡單的日誌表示通過經紀人的消息,再加上你不想打包和解包本地圖這往往會增加一些開銷。

同樣的事情也適用於客戶端,其中一些消息可以根據消息屬性等被忽略,因此您不希望不加任何理由解組映射的開銷。

+0

感謝您的解釋。爲什麼總是很高興知道。 – Mayoares

+0

我剛剛遇到這個,它看起來像一個非常糟糕的行爲。 TRACE級別的日誌記錄會記錄所有消息,而不用解包內容。如果有人對消息調用toString,他很可能想看到內容。如果他不想看到它,他不會調用toString。不打開toString調用似乎是一個毫無意義的優化。 – mabn

+0

你知道他們對意見的評價... –