一、JMS消息组成格式
整个JMS协议组成结构如下:
结构 | 描述 |
---|---|
JMS Provider | 消息中间件/消息服务器 |
JMS Producer | 消息生产者 |
JMS Consumer | 消息消费者 |
JMS Message | 消息 |
JMS Message消息由三部分组成:
- 消息头
- 消息体
- 消息属性
二、JMS 消息头
JMS消息头预定义了若干字段用于客户端与JMS提供者之间识别和发送小于,预编译头如下(红色为重要消息头):
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Ch03ActiveMqSpringBootApplication.class)
public class SpringBootProducer {
@Autowired
JmsTemplate jmsTemplate;
@Test
public void queueSendTest(){
jmsTemplate.send("springboot_queue", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
TextMessage message = session.createTextMessage("Test Message header");
message.setJMSCorrelationID("2000");//可设置成功
message.setJMSPriority(8); //不能设置成功
message.setJMSMessageID("30000"); //不能设置成功
return message;
}
});
}
}
@Component
public class TopicListener {
@JmsListener(destination = "${activemq.name}")
public void receiveMessage(Message message) throws JMSException {
if(message instanceof TextMessage){
TextMessage textMessage = (TextMessage) message;
System.out.println("JMSCorrelationID" + message.getJMSCorrelationID()); //JMSCorrelationID2000
System.out.println("JMSPriority" + message.getJMSPriority());//JMSPriority4
System.out.println("JMSMessageID" + message.getJMSMessageID());//JMSMessageIDID:DESKTOP-2TD06RH-53663-1596375761970-1:1:1:1:1
System.out.println("received message from springboot_queue: " + textMessage.getText());//received message from springboot_queue: Test Message header
}
}
}
三、消息体
在消息体中,JMS API定义了五种类型的消息格式,让我们可以用不同的形式发送和接受消息:
- TextMessage:一个字符串对象(常用)
- MapMessage:一套键-值对
- ObjectMessage:一个序列化的Java对象(常用)
- BytesMessage:一个子接的主句流, 可用于传输文件(常用)
- StreamMessage:Java原始值的数据流
1. TextMessage
可参考上面代码
2. MapMessage
@Test
public void mapMessageSendTest(){
jmsTemplate.send("springboot_queue", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
MapMessage message = session.createMapMessage();
message.setString("name","Vivi");
message.setInt("age", 16);
return message;
}
});
}
@JmsListener(destination = "${activemq.name}")
public void ObjectMessageTest(Message message) throws JMSException {
if(message instanceof MapMessage){
MapMessage mapMessage = (MapMessage) message;
System.out.println(mapMessage.getString("name"));
System.out.println(mapMessage.getInt("age"));
}
}
3. ObjectMessage
注意:
- producer和listener的entity要序列化
- producer和listener的entity所在的包名要一致
- listener中要设置:spring.packages.trust-all: true #添加所有包到信任列表
发message到queue:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Ch03ActiveMqSpringBootApplication.class)
public class SpringBootProducer {
@Autowired
JmsMessagingTemplate jmsMessagingTemplate;
@Test
public void objectMessageSendTest(){
User user = new User("Vivi", 20);
jmsMessagingTemplate.convertAndSend("springboot_queue", user);
}
}
收queue上的message:
@Component
public class TopicListener {
@JmsListener(destination = "${activemq.name}")
public void ObjectMessageTest(Message message) throws JMSException {
if(message instanceof ObjectMessage){
ObjectMessage objectMessage = (ObjectMessage) message;
User user = (User) objectMessage.getObject();
System.out.println("received message from springboot_queue: " + user);
}
}
}
Entity:
package com.learning.activemq.entity;
import java.io.Serializable;
public class User implements Serializable {
private String name;
private int age;
...此处省略set/get/构造方法...
}
4. BytesMessage
发消息:
@Test
public void bytesMessageSendTest() throws FileNotFoundException {
jmsTemplate.send("springboot_queue", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
BytesMessage bytesMessage =session.createBytesMessage();
//1.读取文件
File file = new File("c:/tmp/qq.jpg");
//2.构建文件输入流
try {
FileInputStream inputStream = new FileInputStream(file);
//3.把文件流写入到缓存数组中
byte[] buffer = new byte[(int) file.length()];
inputStream.read(buffer);
//4.把缓存数组写入到BytesMessage中
bytesMessage.writeBytes(buffer);
} catch (Exception e) {
e.printStackTrace();
}
return bytesMessage;
}
});
}
收消息:
@JmsListener(destination = "${activemq.name}")
public void bytesMessageTest(Message message) throws JMSException, IOException {
if(message instanceof BytesMessage){
BytesMessage bytesMessage = (BytesMessage) message;
//1.设计缓存数组
byte[] buffer = new byte[(int) bytesMessage.getBodyLength()];
//2.把字节消息的内容写到缓存数组
bytesMessage.readBytes(buffer);
//3.构建文件输出流
FileOutputStream outputStream = new FileOutputStream("c:/tmp/test.jpg");
//4.把数据写出到本地硬盘
outputStream.write(buffer);
System.out.println("receive message successfully");
}
}
5. StreamMessage
发消息:
@Test
public void streamMessageSendTest() {
jmsTemplate.send("springboot_queue", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
StreamMessage message = session.createStreamMessage();
message.writeString("hello!!!");
message.writeInt(1234);
return message;
}
});
}
收消息:
@JmsListener(destination = "${activemq.name}")
public void bytesMessageTest(Message message) throws JMSException, IOException {
if(message instanceof StreamMessage){
StreamMessage streamMessage = (StreamMessage) message;
System.out.println(streamMessage.readString());
System.out.println(streamMessage.readInt());
System.out.println("receive message successfully");
}
}