二、Spring整合JMS(一)——基于ActiveMQ实现
四、Spring整合JMS(三)——MessageConverter消息转换器
消息转换器MessageConverter
MessageConverter的作用主要有两方面,一方面它可以把我们的非标准化Message对象转换成我们的目标Message对象,这主要是用在发送消息的时候;另一方面它又可以把我们的Message对象转换成对应的目标对象,这主要是用在接收消息的时候。
下面我们就拿发送一个对象消息来举例,假设我们有这样一个需求:我们平台有一个发送邮件的功能,进行发送的时候我们只是把我们的相关信息封装成一个JMS消息,然后利用JMS进行发送,在对应的消息监听器进行接收到的消息处理时才真正的进行消息发送。
假设我们有这么一个Email对象:
package cn.tzz.jms.activemq.spring.obj; import java.io.Serializable; public class Email implements Serializable { private static final long serialVersionUID = 1L; private String receiver; private String title; private String content; public Email(String receiver, String title, String content) { this.receiver = receiver; this.title = title; this.content = content; } public String getReceiver() { return receiver; } public void setReceiver(String receiver) { this.receiver = receiver; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "Email [receiver=" + receiver + ", title=" + title + ", content=" + content + "]"; } }
这个时候我们就需要定义我们的MessageConverter了。要定义自己的MessageConverter很简单,只需要实现Spring为我们提供的MessageConverter接口即可。我们先来看一下Spring MessageConverter接口的定义:
import java.io.Serializable; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.ObjectMessage; import javax.jms.Session; import org.springframework.jms.support.converter.MessageConverter; public class EmailMessageConverter implements MessageConverter { public Message toMessage(Object object, Session session) { ObjectMessage objectMessage = null; try { objectMessage = session.createObjectMessage((Serializable) object); } catch (JMSException e) { e.printStackTrace(); } return objectMessage; } public Object fromMessage(Message message) { ObjectMessage objMessage = null; Serializable serializable = null; try { objMessage = (ObjectMessage) message; serializable = objMessage.getObject(); } catch (JMSException e) { e.printStackTrace(); } return serializable; } }
这样当我们利用JmsTemplate的convertAndSend方法发送一个Email对象的时候就会把对应的Email对象当做参数调用我们定义好的EmailMessageConverter的toMessage方法。
定义好我们的EmailMessageConverter之后就需要指定我们用来发送Email对象的JmsTemplate对象的messageConverter为EmailMessageConverter,这里我们在Spring的配置文件中定义JmsTemplate bean的时候就指定:
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> <property name="connectionFactory" ref="connectionFactory" /> <!-- 消息转换器 --> <property name="messageConverter" ref="emailMessageConverter"/> </bean> <!-- 类型转换器 --> <bean id="emailMessageConverter" class="cn.tzz.jms.activemq.spring.obj.service.impl.EmailMessageConverter"/>
上面destination对应的接收处理的MessageListener方法如下所示:
public class ConsumerObjMessageListener implements MessageListener { public void onMessage(Message message) { if (message instanceof ObjectMessage) { ObjectMessage objMessage = (ObjectMessage) message; try { Object obj = objMessage.getObject(); Email email = (Email) obj; System.out.println("接收到一个ObjectMessage,包含Email对象。"); System.out.println(email); } catch (JMSException e) { e.printStackTrace(); } } } }
之前说了MessageConverter有两方面的功能,除了把Java对象转换成对应的Jms Message之外还可以把Jms Message转换成对应的Java对象。我们看上面的消息监听器在接收消息的时候接收到的就是一个Jms Message,如果我们要利用MessageConverter来把它转换成对应的Java对象的话,只能是我们往里面注入一个对应的MessageConverter,然后在里面手动的调用,如:
当我们使用MessageListenerAdapter来作为消息监听器的时候,我们可以为它指定一个对应的MessageConverter,这样Spring在处理接收到的消息的时候就会自动地利用我们指定的MessageConverter对它进行转换,然后把转换后的Java对象作为参数调用指定的消息处理方法。这里我们再把前面讲解MessageListenerAdapter时定义的MessageListenerAdapter拿来做一个测试,我们指定它的MessageConverter为我们定义好的EmailMessageConverter。
然后在我们的真正用于处理接收到的消息的ConsumerListener中添加一个receiveMessage方法,添加后其代码如下所示:
然后我们定义如下测试代码:
因为我们给MessageListenerAdapter指定了一个MessageConverter,而且是一个EmailMessageConverter,所以当MessageListenerAdapter接收到一个消息后,它会调用我们指定的MessageConverter的fromMessage方法把它转换成一个Java对象,根据定义这里会转换成一个Email对象,然后会把这个Email对象作为参数调用我们通过defaultListenerMethod属性指定的默认处理器方法,根据定义这里就是receiveMessage方法,但是我们可以看到在ConsumerListener中我们一共定义了两个receiveMessage方法,因为是通过转换后的Email对象作为参数进行方法调用的,所以这里调用的就应该是参数类型为Email的receiveMessage方法了。
上述测试代码运行后会输出如下结果:
接收到一个ObjectMessage,包含Email对象。
Email [receiver=test@qq.com, title=测试, content=HellWorld]
说到这里可能有读者就会有疑问了,说我们在之前讲解MessageListenerAdapter的时候不是没有指定对应的MessageConverter,然后发送了一个TextMessage,结果Spring还是把它转换成一个String对象,调用了ConsumerListener参数类型为String的receiveMessage方法吗?那你这个MessageConverter在MessageListenerAdapter进行消息接收的时候也没什么用啊。
其实还是有用的,在我们使用MessageListenerAdapter时,在对其进行初始化也就是调用其构造方法时,它会默认new一个Spring已经为我们实现了的MessageConverter——SimpleMessageConverter作为其默认的MessageConverter,这也就是为什么我们在使用MessageListenerAdapter的时候不需要指定MessageConverter但是消息还是会转换成对应的Java对象的原因。所以默认情况下我们使用MessageListenerAdapter时其对应的MessageListener的处理器方法参数类型必须是一个普通Java对象,而不能是对应的Jms Message对象。
那如果我们在处理Jms Message的时候想使用MessageListenerAdapter,然后又希望处理最原始的Message,而不是经过MessageConverter进行转换后的Message该怎么办呢?这个时候我们只需要在定义MessageListenerAdapter的时候指定其MessageConverter为空就可以了。
<!-- 消息监听适配器 --> <bean id="messageListenerAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"> <property name="delegate"> <bean class="com.tiantian.springintejms.listener.ConsumerListener"/> </property> <property name="defaultListenerMethod" value="receiveMessage"/> <property name="messageConverter"> <null/> </property> </bean>
那么这个时候我们的真实MessageListener的处理器方法参数类型就应该是Jms Message或对应的Jms Message子类型了,不然就会调用不到对应的处理方法了。这里因为我们发送的是一个ObjectMessage,所以这里就添加一个对应的参数类型为ObjectMessage的receiveMessage方法了。
public void receiveMessage(ObjectMessage message) throws JMSException { System.out.println(message.getObject()); }
刚刚讲到Spring已经为我们实现了一个简单的MessageConverter,即org.springframework.jms.support.converter.SimpleMessageConverter,其实Spring在初始化JmsTemplate的时候也指定了其对应的MessageConverter为一个SimpleMessageConverter,所以如果我们平常没有什么特殊要求的时候可以直接使用JmsTemplate的convertAndSend系列方法进行消息发送,而不必繁琐的在调用send方法时自己new一个MessageCreator进行相应Message的创建。
相关推荐
NULL 博文链接:https://elim.iteye.com/blog/1900937
在Spring整合JMS的应用中,如果我们要进行本地的事务管理的话非常简单,只需要在定义对应的消息监听容器时指定其sessionTransacted属性为true,如: <bean id="jmsContainer" class="org.springframework.jms....
基于springboot集成mybatis、durid和自定义消息转换项目,实现阿里巴巴的durid对数据库连接池的设置和自定义消息转换的messageconverter,能够快速开发自己的应用。
春云流兔Spring Cloud Stream示例展示了各种消息交换模式。 该项目基于Baeldung构建的SCS示例,并进行了修改以与Elmhurst版本或更高版本一起使用。 示例包括: MessageConverter:样本处理器应用程序,它接收一条...
MessageConverter MessageCreator MessageEOFException MessageFormatException MessageListenerAdapter MessageListenerAdapter102 MessageNotReadableException MessageNotWriteableException ...
几乎是网上 能找到的 日志脱敏的所有实现 1、基于正则表达式的 日志脱敏实现 ,扩展logback 、log4j 2、springmvc 返回报文脱敏。 3、基于注解方式的脱敏。 大家选择使用。
Excel解析器 Excel Parser提供了一个功能,可以轻松地从Spring引导应用程序中提取Excel数据。 使用Apache POI库对API进行了抽象,并且通过使用Excel Parser,用户可以专注于编写业务逻辑。 同时支持DOM类型...
json 客户监听器模式hystrix工作方式kafka kafka api 流简单实现验证别名注释注解派生aop切面,过滤器,拦截器安全resttemplate自定义restTemplate 拼写作用域resttemplate自定义其余MessageConverter数据格式转换编...
对于日志脱敏的方式有很多,常见的有①使用conversionRule标签,继承MessageConverter②书写一个脱敏工具类,在打印日志的时候对特定特字段进行脱敏返回。 两种方式各有优缺点:第一种方式需要修改代码,不符合开闭...
相当于注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个bean, 配置一些messageconverter。即解决了@Controller注解的使用前提配置。
配置一些messageconverter。即解决了@Controller注解的使用前提配置是对包进行扫描,实现注释驱动Bean定义,同时将bean自动注入容器中使用。即解决了@Controller标识的类的bean的注入和使用。
在Eclipse中导入项目 确保bin / io / confluent / connect / rabbitmq / MessageConverter.class已编译 运行path.sh以在out / kafka-connect-rabbitmq-1.0.0-preview_patch.jar中生成修补的lib