消息监听适配器:具体消息的消费逻辑,适配成 MessageListenerAdapter 定义的格式
默认的方法签名为:void handleMessage(byte[] messageBody)
/*** 自定义的消费监听*/
public classMessageDelegate {/***这个handleMessage方法名要根据org.springframework.amqp.rabbit.listener.adapter包下的
* MessageListenerAdapter.ORIGINAL_DEFAULT_LISTENER_METHOD的默认值来确定*/
public void handleMessage(byte[] messageBody) {
System.err.println("默认方法, 消息内容:" + newString(messageBody));
}
}
handleMessage 方法名要根据 org.springframework.amqp.rabbit.listener.adapter 包下 MessageListenerAdapter.ORIGINAL_DEFAULT_LISTENER_METHOD 的默认值来确定
@BeanpublicSimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer messageListenerContainer= newSimpleMessageListenerContainer(connectionFactory);
messageListenerContainer.setQueues(topicQueue(), topicQueueAgain());
messageListenerContainer.setConcurrentConsumers(1);
messageListenerContainer.setMaxConcurrentConsumers(5);
messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
messageListenerContainer.setConsumerTagStrategy(queue-> queue + "_" +UUID.randomUUID().toString());
MessageListenerAdapter listenerAdapter= new MessageListenerAdapter(newMessageDelegate());
messageListenerContainer.setMessageListener(listenerAdapter);returnmessageListenerContainer;
}
测试
@Testpublic voidsendMessage(){
MessageProperties messageProperties= newMessageProperties();
messageProperties.getHeaders().put("desc","自定义描述");
messageProperties.getHeaders().put("type","自定义类型");
Message message= new Message("hello message".getBytes(), messageProperties);
rabbitTemplate.convertAndSend("topic.exchange","user.abc",message);
}
自定义消费方法
@Slf4jpublic classMessageDelegate {public void handleMessage(byte[] messageBody) {
log.info("默认方法 消息内容:" + newString(messageBody));
}public void consumerMessage(byte[] messageBody){
log.info("字节数据方法 消息的内容 "+newString(messageBody));
}
}
@BeanpublicSimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer messageListenerContainer= newSimpleMessageListenerContainer(connectionFactory);
messageListenerContainer.setQueues(topicQueue(), topicQueueAgain());
messageListenerContainer.setConcurrentConsumers(1);
messageListenerContainer.setMaxConcurrentConsumers(5);
messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
messageListenerContainer.setConsumerTagStrategy(queue-> queue + "_" +UUID.randomUUID().toString());
MessageListenerAdapter listenerAdapter= new MessageListenerAdapter(newMessageDelegate());
listenerAdapter.setDefaultListenerMethod("consumerMessage");
messageListenerContainer.setMessageListener(listenerAdapter);return messageListenerContainer;
byte[] 和 String 间的转换器
public class TextMessageConverter implementsMessageConverter {
@Overridepublic Message toMessage(Object obj, MessageProperties messageProperties) throwsMessageConversionException {return newMessage(obj.toString().getBytes(), messageProperties);
}
@Overridepublic Object fromMessage(Message message) throwsMessageConversionException {
String contentType=message.getMessageProperties().getContentType();if(contentType !=null && contentType.contains("text")){return newString(message.getBody());
}returnmessage.getBody();
}
}
添加String接受方法
public voidconsumerMessage(String messageBody) {
log.info("字符串方法 消息内容:" +messageBody);
}
@BeanpublicSimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer messageListenerContainer= newSimpleMessageListenerContainer(connectionFactory);
messageListenerContainer.setQueues(topicQueue(), topicQueueAgain());
messageListenerContainer.setConcurrentConsumers(1);
messageListenerContainer.setMaxConcurrentConsumers(5);
messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
messageListenerContainer.setConsumerTagStrategy(queue-> queue + "_" +UUID.randomUUID().toString());
MessageListenerAdapter listenerAdapter= new MessageListenerAdapter(newMessageDelegate());
listenerAdapter.setDefaultListenerMethod("consumerMessage");
listenerAdapter.setMessageConverter(newTextMessageConverter());
messageListenerContainer.setMessageListener(listenerAdapter);return messageListenerContainer;
}
测试
@Testpublic voidsendMessage(){
MessageProperties messageProperties= newMessageProperties();
messageProperties.getHeaders().put("desc","自定义描述");
messageProperties.getHeaders().put("type","自定义类型");
messageProperties.setContentType("text/plain");
Message message= new Message("hello message".getBytes(), messageProperties);
rabbitTemplate.convertAndSend("topic.exchange","user.abc",message);
}
不同队列由不同方法消费
@Slf4jpublic classMessageDelegate {public voidmethod1(String messageBody) {
log.info("method1收到的消息:" +messageBody);
}public voidmethod2(String messageBody) {
log.info("method2收到的消息:" +messageBody);
}
}
@BeanpublicSimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer messageListenerContainer= newSimpleMessageListenerContainer(connectionFactory);
messageListenerContainer.setQueues(topicQueue(), topicQueueAgain());
messageListenerContainer.setConcurrentConsumers(1);
messageListenerContainer.setMaxConcurrentConsumers(5);
messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
messageListenerContainer.setConsumerTagStrategy(queue-> queue + "_" +UUID.randomUUID().toString());
MessageListenerAdapter listenerAdapter= new MessageListenerAdapter(newMessageDelegate());
listenerAdapter.setMessageConverter(newTextMessageConverter());
Map queueOrTagToMethod=new HashMap<>();
queueOrTagToMethod.put("topic.queue","method1");
queueOrTagToMethod.put("topic.again","method2");
listenerAdapter.setQueueOrTagToMethodName(queueOrTagToMethod);
messageListenerContainer.setMessageListener(listenerAdapter);return messageListenerContainer;
}
发送JSON使用Map接受消息
@Slf4jpublic classMessageDelegate {public voidconsumerMessage(Map messageBody) {
log.info("消息的内容:" +messageBody);
}
}
添加消息转换器
@BeanpublicSimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer messageListenerContainer= newSimpleMessageListenerContainer(connectionFactory);
messageListenerContainer.setQueues(topicQueue(), topicQueueAgain());
messageListenerContainer.setConcurrentConsumers(1);
messageListenerContainer.setMaxConcurrentConsumers(5);
messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
messageListenerContainer.setConsumerTagStrategy(queue-> queue + "_" +UUID.randomUUID().toString());
MessageListenerAdapter listenerAdapter= new MessageListenerAdapter(newMessageDelegate());
listenerAdapter.setDefaultListenerMethod("consumerMessage");
Jackson2JsonMessageConverter jackson2JsonMessageConverter= newJackson2JsonMessageConverter();
listenerAdapter.setMessageConverter(jackson2JsonMessageConverter);
messageListenerContainer.setMessageListener(listenerAdapter);returnmessageListenerContainer;
}
测试
@Testpublic voidsendJSONMessage(){
Order order= newOrder();
order.setId("0001");
order.setName("放飞梦想");
order.setContent("不服就干");
String str=JSON.toJSONString(order);
MessageProperties messageProperties= newMessageProperties();
messageProperties.setContentType("application/json");
Message message= newMessage(str.getBytes(), messageProperties);
rabbitTemplate.convertAndSend("topic.exchange","user.abc",message);
}
JSON转换成JAVA对象
处理方法
public voidconsumerMessage(Order order) {
log.info("order对象,消息的内容,id:" + order.getId() + "name:" + order.getName() + " content:" +order.getContent());
}
配置DefaultJackson2JavaTypeMapper将JSON转为JAVA对象
@BeanpublicSimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer messageListenerContainer= newSimpleMessageListenerContainer(connectionFactory);
messageListenerContainer.setQueues(topicQueue(), topicQueueAgain());
messageListenerContainer.setConcurrentConsumers(1);
messageListenerContainer.setMaxConcurrentConsumers(5);
messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
messageListenerContainer.setConsumerTagStrategy(queue-> queue + "_" +UUID.randomUUID().toString());
MessageListenerAdapter listenerAdapter= new MessageListenerAdapter(newMessageDelegate());
listenerAdapter.setDefaultListenerMethod("consumerMessage");
Jackson2JsonMessageConverter jackson2JsonMessageConverter= newJackson2JsonMessageConverter();
DefaultJackson2JavaTypeMapper javaTypeMapper= newDefaultJackson2JavaTypeMapper();
javaTypeMapper.setTrustedPackages("com.smart.domain");
jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);
listenerAdapter.setMessageConverter(jackson2JsonMessageConverter);
messageListenerContainer.setMessageListener(listenerAdapter);returnmessageListenerContainer;
}
pdf转换器
@Slf4jpublic class PDFMessageConverter implementsMessageConverter {
@Overridepublic Message toMessage(Object o, MessageProperties messageProperties) throwsMessageConversionException {throw new MessageConversionException(" convert error ! ");
}
@Overridepublic Object fromMessage(Message message) throwsMessageConversionException {
log.info("-----------pdfMessageConverter---------------");byte[] body =message.getBody();
String fileName=UUID.randomUUID().toString();
String path= "d:/test/" + fileName + ".pdf";
File file= newFile(path);try{
Files.copy(newByteArrayInputStream(body), file.toPath());
}catch(IOException e) {
e.printStackTrace();
}returnfile;
}
}
图片转换器
@Slf4jpublic class ImageMessageConverter implementsMessageConverter {
@Overridepublic Message toMessage(Object o, MessageProperties messageProperties) throwsMessageConversionException {throw new MessageConversionException(" convert error ! ");
}
@Overridepublic Object fromMessage(Message message) throwsMessageConversionException {
log.info("------------imageMessageConverter-------------------");
Object _extName= message.getMessageProperties().getHeaders().get("extName");
String extName= _extName == null ? "png": _extName.toString();byte[] messageBody =message.getBody();
String fileName=UUID.randomUUID().toString();
String filePrefix= "d:/test/";
File fileDir= newFile(filePrefix);if (!fileDir.exists()) {
fileDir.mkdirs();
}
String path= filePrefix + fileName + "." +extName;
File file= newFile(path);try{
Files.copy(newByteArrayInputStream(messageBody), file.toPath());
}catch(IOException e) {
e.printStackTrace();
}returnfile;
}
}
整合多个转化器
@BeanpublicSimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer messageListenerContainer= newSimpleMessageListenerContainer(connectionFactory);
messageListenerContainer.setQueues(topicQueue(), topicQueueAgain());
messageListenerContainer.setConcurrentConsumers(1);
messageListenerContainer.setMaxConcurrentConsumers(5);
messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
messageListenerContainer.setConsumerTagStrategy(queue-> queue + "_" +UUID.randomUUID().toString());
MessageListenerAdapter listenerAdapter= new MessageListenerAdapter(newMessageDelegate());
listenerAdapter.setDefaultListenerMethod("consumerMessage");
ContentTypeDelegatingMessageConverter messageConverter= newContentTypeDelegatingMessageConverter();
ImageMessageConverter imageMessageConverter= newImageMessageConverter();
messageConverter.addDelegate("image/png", imageMessageConverter);
messageConverter.addDelegate("image", imageMessageConverter);
PDFMessageConverter pdfMessageConverter= newPDFMessageConverter();
messageConverter.addDelegate("application/pdf", pdfMessageConverter);
listenerAdapter.setMessageConverter(messageConverter);
messageListenerContainer.setMessageListener(listenerAdapter);returnmessageListenerContainer;
}
}
定义文件的消费方法
public classMessageDelegate {public voidconsumeMessage(File file) {
System.err.println("文件对象 方法, 消息内容:" +file.getName());
}
}
测试
@Testpublic void sendExtMessage() throwsIOException {byte[] body = Files.readAllBytes(Paths.get("d:/", "cc.jpg"));
MessageProperties messageProperties= newMessageProperties();
messageProperties.setContentType("image/png");
messageProperties.getHeaders().put("extName","png");
Message message= newMessage(body, messageProperties);
rabbitTemplate.send("topic.exchange","user.ddd",message);
}