我正在使用RabbitMQ处理Spring AMQP,我使用MessageConverter( Jackson2JsonMessageConverter)
配置了ObjectMapper
。如果我通过传递convertAndSend(,,,)
从发件人类调用HashMap<String,Object>
方法,则Receiver
类handleMessage()
方法成功获得了类型HashMap
的消息。但问题是,此HashMap
包含List
字符串List<String>
。当我在HashMap
中收到此Receiver
时,我尝试通过密钥获取List<String>
,但却发出错误List<Object> can't cast Object list to string list
。这是我的Config
类,发件人类和Receiver类
@Configuration
public class RabbitMQConfig {
@Autowired
Environment environment;
final static String paymentQueue = "mobily-payment-queue";
final static String mailQueue = "mobily-mail-queue";
final static String orderQueue = "mobily-order-queue";
final static String deductProductQueue = "mobily-deduct-product-queue";
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(environment.getRequiredProperty("rabbitmq.host"),Integer.parseInt(environment.getRequiredProperty("rabbitmq.port")));
connectionFactory.setUsername(environment.getRequiredProperty("rabbitmq.user"));
connectionFactory.setPassword(environment.getRequiredProperty("rabbitmq.pass"));
return connectionFactory;
}
@Bean
public MessageConverter jsonMessageConverter() {
final Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
mapper.registerModule(new Hibernate4Module());
mapper.setSerializationInclusion(Include.NON_NULL);
converter.setJsonObjectMapper(mapper);
return converter;
}
@Bean
public RabbitTemplate template(MessageConverter jsonMessageConverter) {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
template.setMessageConverter(jsonMessageConverter);
return template;
}
@Bean
public DirectExchange direct() {
return new DirectExchange("mobily.direct");
}
@Bean
public Queue paymentQueue(){
return new Queue(paymentQueue);
}
@Bean
public Queue deductProductQueue() {
return new Queue(deductProductQueue);
}
@Bean
public Queue orderQueue() {
return new Queue(orderQueue);
}
@Bean
public Queue mailQueue(){
return new Queue(mailQueue);
}
@Bean
public Binding paymentBinding(DirectExchange direct, Queue paymentQueue) {
return BindingBuilder.bind(paymentQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.payment.key"));
}
@Bean
public Binding deductProductBinding(DirectExchange direct, Queue deductProductQueue) {
return BindingBuilder.bind(deductProductQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.deduct.product.key"));
}
@Bean
public Binding orderBinding(DirectExchange direct, Queue orderQueue) {
return BindingBuilder.bind(orderQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.order.key"));
}
@Bean
public Binding mailBinding(DirectExchange direct, Queue mailQueue) {
return BindingBuilder.bind(mailQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.mail.key"));
}
/*@Bean
Receiver receiver() {
return new Receiver();
}*/
@Bean
PaymentReceiver paymentReceiver(){
return new PaymentReceiver();
}
@Bean
DeductProductReceiver deductProductReceiver(){
return new DeductProductReceiver();
}
@Bean
OrderReceiver orderReceiver(){
return new OrderReceiver();
}
@Bean
MailReceiver mailReceiver(){
return new MailReceiver();
}
@Bean
SimpleMessageListenerContainer deductProductContainer(ConnectionFactory connectionFactory, MessageListenerAdapter deductProductListenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(deductProductQueue);
container.setMessageListener(deductProductListenerAdapter);
return container;
}
@Bean
MessageListenerAdapter deductProductListenerAdapter(DeductProductReceiver deductProductReceiver,MessageConverter jsonMessageConverter) {
return new MessageListenerAdapter(deductProductReceiver, jsonMessageConverter);
}
@Bean
SimpleMessageListenerContainer paymentContainer(ConnectionFactory connectionFactory, MessageListenerAdapter paymentListenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(paymentQueue);
container.setMessageListener(paymentListenerAdapter);
return container;
}
@Bean
MessageListenerAdapter paymentListenerAdapter(PaymentReceiver paymentReceiver,MessageConverter jsonMessageConverter) {
return new MessageListenerAdapter(paymentReceiver,jsonMessageConverter );
}
@Bean
SimpleMessageListenerContainer orderContainer(ConnectionFactory connectionFactory, MessageListenerAdapter orderListenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(orderQueue);
container.setMessageListener(orderListenerAdapter);
return container;
}
@Bean
MessageListenerAdapter orderListenerAdapter(OrderReceiver orderReceiver,MessageConverter jsonMessageConverter) {
return new MessageListenerAdapter(orderReceiver,jsonMessageConverter);
}
@Bean
SimpleMessageListenerContainer mailContainer(ConnectionFactory connectionFactory, MessageListenerAdapter mailListenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(mailQueue);
container.setMessageListener(mailListenerAdapter);
return container;
}
@Bean
MessageListenerAdapter mailListenerAdapter(MailReceiver mailReceiver,MessageConverter jsonMessageConverter) {
return new MessageListenerAdapter(mailReceiver,jsonMessageConverter);
}
}
这是我的发件人类
HashMap<String, Object> mailMap=new HashMap<String, Object>();
CustomerAccountUser customerAccountUser=customerAccountUserService.getCustomerAccountUserByUsername(customerAccountPayments.getCustomerName());
ArrayList<String> emailAddress=new ArrayList<String>();
emailAddress.add(customerAccountUser.getEmail());
template.convertAndSend(direct.getName(),environment.getRequiredProperty("rabbitmq.mail.key"),mailMap);
这是我的接收者
public void handleMessage(HashMap<String,Object> mailMap){
try{
System.out.println("mail queue..................................." + mailMap);
String s1=(String)mailMap.get("subject");
String s2=(String)mailMap.get("body");
List<String> list=(List<String>)mailMap.get("emailAddress");
}
}
这个错误
e2016-05-24 17:02:47 ERROR stderr:71 - java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
2016-05-24 17:02:47 ERROR stderr:71 - at com.mobily.service.EmailService.sendEmail(EmailService.java:24)
2016-05-24 17:02:47 INFO stdout:71 - values
2016-05-24 17:02:47 ERROR stderr:71 - at com.mobily.customer.rabbitmq.reciever.MailReceiver.handleMessage(MailReceiver.java:27)
2016-05-24 17:02:47 ERROR stderr:71 - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2016-05-24 17:02:47 ERROR stderr:71 - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2016-05-24 17:02:47 ERROR stderr:71 - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2016-05-24 17:02:47 ERROR stderr:71 - at java.lang.reflect.Method.invoke(Method.java:497)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:387)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:298)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:757)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:680)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:93)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:183)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1358)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:661)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1102)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1086)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1100(SimpleMessageListenerContainer.java:93)
2016-05-24 17:02:47 ERROR stderr:71 - at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1203)`enter code here`e
答案 0 :(得分:2)
嗯,遗憾的是Jackson2JsonMessageConverter
无法为您做到这一点。
它的逻辑基于三个消息标题:
public static final String DEFAULT_CLASSID_FIELD_NAME = "__TypeId__";
public static final String DEFAULT_CONTENT_CLASSID_FIELD_NAME = "__ContentTypeId__";
public static final String DEFAULT_KEY_CLASSID_FIELD_NAME = "__KeyTypeId__";
因此,它能做的最好的事情就像HashMap<Foo, Bar>
。但是它无法构建正确的嵌套容器类型,因为消息头中没有这样的信息。
当然,你必须在handleMessage
代码的下游进行一些进一步的转换(转换)逻辑。我的意思是不要投射到List<String>
,而是迭代并投射每个项目。
虽然根据你的发送逻辑:
ArrayList<String> emailAddress=new ArrayList<String>();
emailAddress.add(customerAccountUser.getEmail());
您可以尝试使用array
(String[]
)代替List<String>
。这应该可以正常工作,因为数组被认为是原始类型,而不是容器。