Spring boot 整合RabbitMQ AMQP实战

RabbitAdmin

RabbitAdmin类可以很好的操作RabbitMQ, 在Spring 中直接进行注入即可

注意:

1、autoStartup 必须要设置为true, 否则Spring 容器不会加载RabbitAdmin类;

2、rabbitAdmin 的底层实现就是从Spring 容器中获取Exchange、Bingding、RoutingKey以及Queue的@Bean声明;

3、然后使用RabbitTemplate的execute方法执行对应的声明、修改、删除等一系列RabbitMq基础功能操作;例如:添加一个交换机、删除一个绑定、晴空一个队列里的消息等等;

看一下目录结构

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>rabbitmq-spring</groupId>
    <artifactId>rabbitmq-spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.1.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.0.4.RELEASE</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

程序入口


@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

rabbitMQ的配置文件

@Configuration
@ComponentScan({"com.lizhi.spring"})
public class RabbitMQConfig {

    @Bean
    public CachingConnectionFactory connectionFactory(){
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses("127.0.0.1:5672");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        return connectionFactory;
    }

    /**
     * connectionFactory 和上面的方法名字一致
     * @param connectionFactory
     * @return
     */
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }


}

测试一下

建立绑定关系

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {

    @Test
    public void contextLoads() {

    }

    @Autowired
    private RabbitAdmin rabbitAdmin;

    @Test
    public void testAdmin() {
        rabbitAdmin.declareExchange(new DirectExchange("test.direct", false, false));
        rabbitAdmin.declareExchange(new TopicExchange("test.topic", false, false));
        rabbitAdmin.declareExchange(new FanoutExchange("test.fanout", false, false));

        rabbitAdmin.declareQueue(new Queue("test.direct.queue", false));
        rabbitAdmin.declareQueue(new Queue("test.topic.queue", false));
        rabbitAdmin.declareQueue(new Queue("test.fanout.queue", false));

        //建立绑定关系,方式1
        rabbitAdmin.declareBinding(new Binding("test.direct.queue",
                Binding.DestinationType.QUEUE,
                "test.direct",
                "direct",
                new HashMap<String, Object>()));

//        方式2 ,
        rabbitAdmin.declareBinding(
                BindingBuilder.bind(new Queue("test.topic.queue", false)) // 直接创建队列
                        .to(new TopicExchange("test.topic", false, false)) // 直接创建交换机的,建立关联关系
                        .with("user.#")); // 指定路由key
//
//        rabbitAdmin.declareBinding(
//                BindingBuilder
//                        .bind(new Queue("test.fanout.queue", false))
//                        .to(new FanoutExchange("test.fanout", false, false)));// fanout 是没有with方法的, 因为fanout是不经过路由key

        rabbitAdmin.declareBinding(
                BindingBuilder
                        .bind(new Queue("test.fanout.queue", false))
                        .to(new FanoutExchange("test.fanout", false, false)));

        // 清空数据
        rabbitAdmin.purgeQueue("test.topic.queue", false);
    }


}

SpringAMQP声明

在RabbitMq基础API里面声明一个Exchange、声明一个绑定、 声明一个队列

在RabbitMq 基础api中

channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);

channel.queueDeclare(queueName, false, false, false, null);

channel.queueBind(queueName, exchangeName, routingKey);

在使用SpringAMQP 去声明,就需要使用SpringAMQP的如下模式,即声明@Bean 方式;

在RabbitMqConfig 中注入

/**
     * 针对消费者配置
     * 1. 设置交换机类型
     * 2. 将队列绑定到交换机
     * FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念
     * HeadersExchange :通过添加属性key-value匹配
     * DirectExchange:按照routingkey分发到指定队列
     * TopicExchange:多关键字匹配
     */
    @Bean
    public TopicExchange topicExchange001() {
        return new TopicExchange("topic001", true, false);
    }

    @Bean
    public Queue queue001() {
        return new Queue("queue001", true); // 队列持久
    }

    @Bean
    public Binding binding001() {
        return BindingBuilder.bind(queue001()).to(topicExchange001()).with("spring.*");
    }

RabbitTemplate(消息模板)

该类提供了丰富的发送消息的方法,包括可靠性投递消息方法、 回调监听的消息接口 ConfirmCallback、返回值确认接口, ReturnCallback 等等, 同样我么需要进行注入到Spring容器中, 然后直接使用;

在 RabbitMQConfig类中添加RabbitTemplate 消息模板

// 消息模板
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);

        return rabbitTemplate;
    }
 // 消息模板发送消息
    @Test
    public void testSendMessage() throws Exception {
        // 创建消息
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.getHeaders().put("desc", "信息描述");
        messageProperties.getHeaders().put("type", "自定义消息类型..");
        Message message = new Message("Hello RabbitMq".getBytes(), messageProperties);
// new MessagePostProcessor()对消息发送之后对消息进行一些其他设置
        rabbitTemplate.convertAndSend("topic001", "spring.amqp", message, new MessagePostProcessor() {

            public Message postProcessMessage(Message message) throws AmqpException {
                System.out.println("---添加额外设置---");
                message.getMessageProperties().getHeaders().put("desc", "额外信息描述");
                message.getMessageProperties().getHeaders().put("attr", "额外新加的属性");
                return message;
            }
        });

    }

@Test
    public void testSendMessage2() throws Exception {
        
        // 方式1
        rabbitTemplate.convertAndSend("topic001", "spring.amqp", "hello object message send");
        rabbitTemplate.convertAndSend("topic002", "rabbit.def", "hello object message send");

        // 方式2
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setContentType("text/plain");
        Message message = new Message("mq 消息1234".getBytes(), messageProperties);
        rabbitTemplate.send("topic001", "spring.abc", message);
        
    }

SimpleMessageListenerContainer(简单消息监听容器)

1、这个类非常的强大, 我们可以对他进行很多设置, 对于消费者的配置项, 这个类都可以满足 , 2, 监听队列(多个队列)、自动启动、自动声明功能,3、设置事务特性、事务管理器、 事务属性、事务容量(并发)、 是否开启事务、消息回滚等 , 4、设置消费者数量、最小最大数量,、批量消费; 5, 设置消息确认和自动确认消息模式、是否重回队列、异常捕获handler函数;6、设置消费者标签生成策略、是否独占模式、消费者属性等; 6、设置具体的监听器、消息转换器等等;

注意 SimpleMessageListenerContainer 可以进行动态设置 , 比如消费者数量 ,接收消息的模式等; 很多基于RabbitMq的自定制在进行动态设置的时候, 也是根据这一特性去实现的。所以可以看出springAMQP是非常强大的;

SimpleMessageListenerContainer 为什么可以动态感知配置变更?

 

看下代码

@Bean
    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
        
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueues(queue001(), queue002(), queue003(), queue_image(), queue_pdf()); // 监听实际的队列
        container.setConcurrentConsumers(1);// 设置当前消费者数量
        container.setMaxConcurrentConsumers(5);  // 设置最大消费者数量
        container.setDefaultRequeueRejected(false);  // 设置是否重回队列
        container.setAcknowledgeMode(AcknowledgeMode.AUTO); // 设置签收方式
        container.setConsumerTagStrategy(new ConsumerTagStrategy() { // 设置消费者标签的生成策略
            public String createConsumerTag(String queue) {
                return queue + "_" + UUID.randomUUID().toString();
            }
        });
        /**
         container.setMessageListener(new ChannelAwareMessageListener() { // 设置message监听
         public void onMessage(Message message, Channel channel) throws Exception {
         String msg = new String(message.getBody());
         System.out.println("-----消费者:"+msg);

         }
         });
         

    }

MessageListenerAdapter(消息监听适配器)

@Bean
    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {

        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueues(queue001(), queue002(), queue003(), queue_image(), queue_pdf()); // 监听实际的队列
        container.setConcurrentConsumers(1);// 设置当前消费者数量
        container.setMaxConcurrentConsumers(5);  // 设置最大消费者数量
        container.setDefaultRequeueRejected(false);  // 设置是否重回队列
        container.setAcknowledgeMode(AcknowledgeMode.AUTO); // 设置签收方式
        container.setConsumerTagStrategy(new ConsumerTagStrategy() { // 设置消费者标签的生成策略
            public String createConsumerTag(String queue) { // queueName
                return queue + "_" + UUID.randomUUID().toString();
            }
        });
       

        /**
         * 1、适配器方式, 默认是有自己的方法名字的; handleMessage
         * 也可以自己指定一个方法的名字:consumeMessage
         * 也可以添加一个转换器, 从字节数据转换成String
         */
        /*MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
        // 自定义方法
        adapter.setDefaultListenerMethod("consumeMessage");
        adapter.setMessageConverter(new TextMessageConverter());
        container.setMessageListener(adapter);
*/
        /**
         * 2、适配器方式我们的对垒名称和方法名称也可以进行一一的匹配
         *
         */
        Map<String, String> queueOrTagToMethodName = new HashMap<String, String>();
        // 队列和方法绑定
        queueOrTagToMethodName.put("queue001", "method1");
        queueOrTagToMethodName.put("queue002", "method2");
        MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
        adapter.setQueueOrTagToMethodName(queueOrTagToMethodName);
        adapter.setMessageConverter(new TextMessageConverter());
        container.setMessageListener(adapter);
        return container;

    }
public class MessageDelegate {

    // 这些名字和参数都是固定的, 否则会报异常

    /**
     * org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Failed to invoke target method 'handleMessage' with argument type = [class [B], value = [{[B@39ee53f9}]
     at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:393) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:298) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1414) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1337) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) ~[spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:817) [spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:801) [spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) [spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1042) [spring-rabbit-2.0.5.RELEASE.jar:2.0.5.RELEASE]
     * @param messageBody
     */

    public void handleMessage(byte[] messageBody){
        System.out.println("默认方法,消息内容:" + new String(messageBody));
    }

    public void consumeMessage(byte[] messageBody){
        System.out.println("自定义方法:消息内容" + new String(messageBody));
    }

    public void consumeMessage(String messageBody){
        System.out.println("自定义 : 参数为字符串" + messageBody);
    }

    public void method1(String messageBody){
        System.out.println("method1 : 收到消息内容" + messageBody);
    }

    public void method2(String messageBody){
        System.out.println("method2 : 收到消息内容" + messageBody);
    }


}
public class TextMessageConverter implements MessageConverter {

    //java 对象转换成 message 对象
    public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {

        return new Message(object.toString().getBytes(), messageProperties);
    }

    // message 对象转换成Java
    public Object fromMessage(Message message) throws MessageConversionException {
        String contentType = message.getMessageProperties().getContentType();
        if (null != contentType && contentType.contains("text")){
            return new String(message.getBody());
        }

        return message.getBody();
    }
}

 

MessageConvertre //消息转换器

1、我们在进行发送消息的时候, 正常情况下消息体为二进制的数据方式进行传输, 如果希望内部帮我们进行转换, 或者指定自定义的转换器,就需要用到MessageConvertre;

2、自定义常用消息转换器: MessageConverter, 一般来讲都需要实现这个接口 重写两个方法 toMessage和fromMessage, String 转换器

public class TextMessageConverter implements MessageConverter {

    //java 对象转换成 message 对象
    public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
        return new Message(object.toString().getBytes(), messageProperties);
    }

    // message 对象转换成Java
    public Object fromMessage(Message message) throws MessageConversionException {
        String contentType = message.getMessageProperties().getContentType();
        if (null != contentType && contentType.contains("text")){
            return new String(message.getBody());
        }

        return message.getBody();
    }
}

添加pom.xml 依赖

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.6</version>
        </dependency>

3、json转换器:Jackson2JsonMessageConverter: 可以进行Java对象的转换功能

@Bean
    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {

        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueues(queue001(), queue002(), queue003(), queue_image(), queue_pdf()); // 监听实际的队列
        container.setConcurrentConsumers(1);// 设置当前消费者数量
        container.setMaxConcurrentConsumers(5);  // 设置最大消费者数量
        container.setDefaultRequeueRejected(false);  // 设置是否重回队列
        container.setAcknowledgeMode(AcknowledgeMode.AUTO); // 设置签收方式
        container.setConsumerTagStrategy(new ConsumerTagStrategy() { // 设置消费者标签的生成策略
            public String createConsumerTag(String queue) { // queueName
                return queue + "_" + UUID.randomUUID().toString();
            }
        });
       


        // 1.1 支持json格式的转换器

         MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
         adapter.setDefaultListenerMethod("consumeMessage");

         Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
         adapter.setMessageConverter(jackson2JsonMessageConverter);

         container.setMessageListener(adapter);
        return container;

    }
public class MessageDelegate {

    public void consumeMessage(Map messageBody) {
        System.err.println("map方法, 消息内容:" + messageBody);
    }

}

@Test
    public void testSendJsonMessage() throws JsonProcessingException {
        Order order = new Order();
        order.setId("001");
        order.setName("消息订单");
        order.setContent("描述信息");

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(order);
        System.err.println("order 4 json: " + json);

        MessageProperties messageProperties = new MessageProperties();
        //这里注意一定要修改contentType为 application/json
        messageProperties.setContentType("application/json");
        Message message = new Message(json.getBytes(), messageProperties);
        rabbitTemplate.send("topic001", "spring.order", message);
    }


最后输出
2018-10-09 20:54:58.701  INFO 51524 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration' of type [org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration$$EnhancerBySpringCGLIB$$6d27a2b0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-10-09 20:54:59.691  INFO 51524 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 2147483647
2018-10-09 20:54:59.707  INFO 51524 --- [enerContainer-1] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2018-10-09 20:54:59.794  INFO 51524 --- [enerContainer-1] o.s.a.r.c.CachingConnectionFactory       : Created new connection: connectionFactory#4a335fa8:0/SimpleConnection@116ee046 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 53738]
2018-10-09 20:54:59.866  INFO 51524 --- [           main] com.lizhi.spring.ApplicationTest         : Started ApplicationTest in 2.957 seconds (JVM running for 4.798)
order 4 json: {"id":"001","name":"消息订单","content":"描述信息"}
2018-10-09 20:55:00.108  INFO 51524 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@73e9cf30: startup date [Tue Oct 09 20:54:57 CST 2018]; root of context hierarchy
2018-10-09 20:55:00.110  INFO 51524 --- [       Thread-2] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 2147483647
2018-10-09 20:55:00.118  INFO 51524 --- [       Thread-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
map方法, 消息内容:{id=001, name=消息订单, content=描述信息}

4、DefaultJackson2JavaTypeMapper 映射器: 可以进行java 对象的映射关系;

MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
         adapter.setDefaultListenerMethod("consumeMessage");
         Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
         DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();

         Map<String, Class<?>> idClassMapping = new HashMap<String, Class<?>>();
         idClassMapping.put("order", Order.class);
        idClassMapping.put("packaged", Packaged.class);

         javaTypeMapper.setIdClassMapping(idClassMapping);

         jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);
         adapter.setMessageConverter(jackson2JsonMessageConverter);
         container.setMessageListener(adapter);
@Test
    public void testSendMappingMessage() throws Exception {

        ObjectMapper mapper = new ObjectMapper();

        Order order = new Order();
        order.setId("001");
        order.setName("订单消息");
        order.setContent("订单描述信息");

        String json1 = mapper.writeValueAsString(order);
        System.err.println("order 4 json: " + json1);

        MessageProperties messageProperties1 = new MessageProperties();
        //这里注意一定要修改contentType为 application/json
        messageProperties1.setContentType("application/json");
        messageProperties1.getHeaders().put("__TypeId__", "order");
        Message message1 = new Message(json1.getBytes(), messageProperties1);
        rabbitTemplate.send("topic001", "spring.order", message1);

        Packaged pack = new Packaged();
        pack.setId("002");
        pack.setName("包裹消息");
        pack.setDescription("包裹描述信息");

        String json2 = mapper.writeValueAsString(pack);
        System.err.println("pack 4 json: " + json2);

        MessageProperties messageProperties2 = new MessageProperties();
        //这里注意一定要修改contentType为 application/json
        messageProperties2.setContentType("application/json");
        messageProperties2.getHeaders().put("__TypeId__", "packaged");
        Message message2 = new Message(json2.getBytes(), messageProperties2);
        rabbitTemplate.send("topic001", "spring.pack", message2);
    }
public void consumeMessage(Order order) {
        System.err.println("order对象, 消息内容, id: " + order.getId() +
                ", name: " + order.getName() +
                ", content: "+ order.getContent());
    }

    public void consumeMessage(Packaged pack) {
        System.err.println("package对象, 消息内容, id: " + pack.getId() +
                ", name: " + pack.getName() +
                ", content: "+ pack.getDescription());
    }

5、自定义二进制转换器:比如图片类型、pdf、ppt、流媒体

public class PDFMessageConverter implements MessageConverter {

	@Override
	public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
		throw new MessageConversionException(" convert error ! ");
	}

	@Override
	public Object fromMessage(Message message) throws MessageConversionException {
		System.err.println("-----------PDF MessageConverter----------");
		
		byte[] body = message.getBody();
		String fileName = UUID.randomUUID().toString();
		String path = "/Users/lizhi/Desktop/" + fileName + ".pdf";
		File f = new File(path);
		try {
			Files.copy(new ByteArrayInputStream(body), f.toPath());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return f;
	}

}
public class ImageMessageConverter implements MessageConverter {

	@Override
	public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
		throw new MessageConversionException(" convert error ! ");
	}

	@Override
	public Object fromMessage(Message message) throws MessageConversionException {
		System.err.println("-----------Image MessageConverter----------");
		
		Object _extName = message.getMessageProperties().getHeaders().get("extName");
		String extName = _extName == null ? "png" : _extName.toString();
		
		byte[] body = message.getBody();
		String fileName = UUID.randomUUID().toString();
		String path = "/Users/lizhi/Desktop/" + fileName + "." + extName;
		File f = new File(path);
		try {
			Files.copy(new ByteArrayInputStream(body), f.toPath());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return f;
	}

}
//1.4 ext convert

        MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
        adapter.setDefaultListenerMethod("consumeMessage");

        //全局的转换器:
        ContentTypeDelegatingMessageConverter convert = new ContentTypeDelegatingMessageConverter();

        TextMessageConverter textConvert = new TextMessageConverter();
        convert.addDelegate("text", textConvert);
        convert.addDelegate("html/text", textConvert);
        convert.addDelegate("xml/text", textConvert);
        convert.addDelegate("text/plain", textConvert);

        Jackson2JsonMessageConverter jsonConvert = new Jackson2JsonMessageConverter();
        convert.addDelegate("json", jsonConvert);
        convert.addDelegate("application/json", jsonConvert);

        ImageMessageConverter imageConverter = new ImageMessageConverter();
        convert.addDelegate("image/png", imageConverter);
        convert.addDelegate("image", imageConverter);

        PDFMessageConverter pdfConverter = new PDFMessageConverter();
        convert.addDelegate("application/pdf", pdfConverter);


        adapter.setMessageConverter(convert);
        container.setMessageListener(adapter);
@Test
    public void testSendExtConverterMessage() throws Exception {
			/*byte[] body = Files.readAllBytes(Paths.get("/Users/lizhi/Desktop/", "地图.png"));
			MessageProperties messageProperties = new MessageProperties();
			messageProperties.setContentType("image/png");
			messageProperties.getHeaders().put("extName", "png");
			Message message = new Message(body, messageProperties);
			rabbitTemplate.send("", "image_queue", message);*/

        byte[] body = Files.readAllBytes(Paths.get("/Users/lizhi/Desktop/", "设计模式之策略模式V4.0.pdf"));
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setContentType("application/pdf");
        Message message = new Message(body, messageProperties);
        rabbitTemplate.send("", "pdf_queue", message);
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值