-
现象:收到消息会打印告警消息::Could not convert incoming message with content-type [null]
-
解决:
RabbitMQ已经实现了Jackson的消息转换(Jackson2JsonMessageConverter),由于考虑到效率,如下使用Gson实现消息转换。
如下消息的转换类的接口MessageConverter,Jackson2JsonMessageConverter的父类AbstractJsonMessageConverter针对json转换的基类。
我们实现Gson2JsonMessageConverter转换类也继承AbstractJsonMessageConverter。
引入Gson的pom
[html]
view plain
copy
-
<dependency>
-
<groupId>com.google.code.gson</groupId>
-
<artifactId>gson</artifactId>
-
<version>2.3</version>
-
</dependency>
转换类实现如下:
[java]
view plain
copy
-
package cn.slimsmart.rabbitmq.demo.spring.tag;
-
-
import java.io.IOException;
-
import java.io.UnsupportedEncodingException;
-
-
import org.apache.commons.logging.Log;
-
import org.apache.commons.logging.LogFactory;
-
import org.springframework.amqp.core.Message;
-
import org.springframework.amqp.core.MessageProperties;
-
import org.springframework.amqp.support.converter.AbstractJsonMessageConverter;
-
import org.springframework.amqp.support.converter.ClassMapper;
-
import org.springframework.amqp.support.converter.DefaultClassMapper;
-
import org.springframework.amqp.support.converter.MessageConversionException;
-
-
import com.google.gson.Gson;
-
-
public class Gson2JsonMessageConverter extends AbstractJsonMessageConverter {
-
-
private static Log log = LogFactory.getLog(Gson2JsonMessageConverter.class);
-
-
private static ClassMapper classMapper = new DefaultClassMapper();
-
-
private static Gson gson = new Gson();
-
-
public Gson2JsonMessageConverter() {
-
super();
-
}
-
-
@Override
-
protected Message createMessage(Object object,
-
MessageProperties messageProperties) {
-
byte[] bytes = null;
-
try {
-
String jsonString = gson.toJson(object);
-
bytes = jsonString.getBytes(getDefaultCharset());
-
}
-
catch (IOException e) {
-
throw new MessageConversionException(
-
"Failed to convert Message content", e);
-
}
-
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
-
messageProperties.setContentEncoding(getDefaultCharset());
-
if (bytes != null) {
-
messageProperties.setContentLength(bytes.length);
-
}
-
classMapper.fromClass(object.getClass(),messageProperties);
-
return new Message(bytes, messageProperties);
-
}
-
-
@Override
-
public Object fromMessage(Message message)
-
throws MessageConversionException {
-
Object content = null;
-
MessageProperties properties = message.getMessageProperties();
-
if (properties != null) {
-
String contentType = properties.getContentType();
-
if (contentType != null && contentType.contains("json")) {
-
String encoding = properties.getContentEncoding();
-
if (encoding == null) {
-
encoding = getDefaultCharset();
-
}
-
try {
-
Class<?> targetClass = getClassMapper().toClass(
-
message.getMessageProperties());
-
content = convertBytesToObject(message.getBody(),
-
encoding, targetClass);
-
}
-
catch (IOException e) {
-
throw new MessageConversionException(
-
"Failed to convert Message content", e);
-
}
-
}
-
else {
-
log.warn("Could not convert incoming message with content-type ["
-
+ contentType + "]");
-
}
-
}
-
if (content == null) {
-
content = message.getBody();
-
}
-
return content;
-
}
-
-
private Object convertBytesToObject(byte[] body, String encoding,
-
Class<?> clazz) throws UnsupportedEncodingException {
-
String contentAsString = new String(body, encoding);
-
return gson.fromJson(contentAsString, clazz);
-
}
-
}
现象:收到消息会打印告警消息::Could not convert incoming message with content-type [null] 解决:RabbitMQ已经实现了Jackson的消息转换(Jackson2JsonMessageConverter),由于考虑到效率,如下使用Gson实现消息转换。如下消息的转换类的接口MessageConverter,Jackson2JsonMessageConverter的父类AbstractJsonMessageConverter针对json转
SpringBoot整合
Rabbitmq
发送接收
消息
实战
另外,博主发起了SpringBoot整合
Rabbitmq
这一系列的gitchat交流会。刚兴趣的童鞋可以进入交流:https://gitbook.cn/gitchat/activity/5b90f9214fb1bd5c9acd4338
交流QQ:1974544863
PayMap
PayMap是一个使用Java语言集成三方支付的小Demo,现已集成支付宝(国内、国际、移动端、PC端)、微信、银联(ACP、UPOP)、光大(网关、网页)、邮政支付,采用的技术栈为:SpringMVC+Spring+MyBatis+Shiro+
RabbitMQ
+Redis。
支持前面提到的各种**支付
支付请求调用...
问题描述:
org.springframework.amqp.rabbit.support.ListenerExecution
Failed
Exception:
Failed
to
convert
message
Caused by: org.springframework.amqp.AmqpException: No method found for class java.lang.String
问题分析:
1、
消息
生产者发送的
消息
类型为String,
消息
消费者接收的
消息
类
支持byte[] 、CharSequence 两种类型直接传输 ,其余对象直接用fastjson转为json字符串传输 。
byte[] 一般用来传输文件 , 而 CharSequence用来传输字符串效率更高。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.amqp.core.
Message
;
impor
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置
RabbitMQ
连接信息,例如在application.properties中添加以下配置:
spring.
rabbitmq
.host=localhost
spring.
rabbitmq
.port=5672
spring.
rabbitmq
.username=guest
spring.
rabbitmq
.password=guest
3.创建一个发送
消息
的工具类,例如AlertSender.java:
@Component
public class AlertSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(String
message
) {
rabbitTemplate.
convert
AndSend("alert.exchange", "alert.key",
message
);
4.在需要发送
告警
消息
的地方调用AlertSender的send方法,例如:
@Autowired
private AlertSender alertSender;
public void doSomething() {
// 发送
告警
消息
alertSender.send("发生了错误!");
5.在
RabbitMQ
中创建exchange和queue,并将它们绑定起来,例如:
@Bean
public DirectExchange alertExchange() {
return new DirectExchange("alert.exchange");
@Bean
public Queue alertQueue() {
return new Queue("alert.queue");
@Bean
public Binding alertBinding(DirectExchange alertExchange, Queue alertQueue) {
return BindingBuilder.bind(alertQueue).to(alertExchange).with("alert.key");
这样就完成了使用SpringBoot和
RabbitMQ
发送
告警
消息
的实现。