我想发送一条包含销售清单的JMS消息,并通过 onMessage() 接收它 . 据我所知, springframework.jms.support.converter.MessageConverter 应该扮演转换或转换消息的角色,所以我不必创建XSD或额外的映射类 . 我的意思是,我期待测试波纹管发送一条消息,并且 (SalesMessage) messageConverter.fromMessage(message) 足以转换并实现 SalesMessage 的对象 .

基本上,错误是 java.lang.ClassCastException: java.lang.String cannot be cast to ...SalesMessage .

我的考试

AnnotationConfigApplicationContext context;

MyMessageSender ms;

JmsListenerEndpointRegistry bean;

@Before

public void setUpBeforeClass() throws Exception {

context = new AnnotationConfigApplicationContext(AppConfig.class);

ms = context.getBean(MyMessageSender.class);

}

@Test

public void test2() {

Sale s = new Sale("product_type", 1L);

List l = new ArrayList();

l.add(s);

SalesMessage sm = new SalesMessage(l, 1);

ms.sendMessage(sm.toString());

bean = context.getBean(JmsListenerEndpointRegistry.class);

for (MessageListenerContainer listenerContainer : bean.getListenerContainers()) {

DefaultMessageListenerContainer container = (DefaultMessageListenerContainer) listenerContainer;

container.shutdown();

}

}

MyJmsListener

@Component

public class MyJmsListener {

@Autowired

private MessageConverter messageConverter;

@JmsListener(destination = AppConfig.QUEUE_NAME)

public void handleMessage(Message message) {

try {

System.out.println("received: "+message);

//this prints received: ActiveMQTextMessage {commandId = 5, ..., jmsXGroupFirstForConsumer = false, text = SalesMessage [sales=[Sale [product_type=produ...ssageType=1]}

SalesMessage salesMessage = (SalesMessage) messageConverter.fromMessage(message); // <<< here is the focus of my question

System.out.println("salesMessage: "+salesMessage);

}

catch(JMSException e) {

e.printStackTrace();

}

}

}

Spring Config

@Configuration

@ComponentScan

@EnableJms

public class AppConfig {

public static final String QUEUE_NAME = "example.queue";

@Bean

public ConnectionFactory connectionFactory() {

ConnectionFactory connectionFactory =

new ActiveMQConnectionFactory("vm://localhost");

return connectionFactory;

}

@Bean

public JmsListenerContainerFactory jmsListenerContainerFactory() {

DefaultJmsListenerContainerFactory factory =

new DefaultJmsListenerContainerFactory();

factory.setConnectionFactory(connectionFactory());

//core poll size=4 threads and max poll size 8 threads

factory.setConcurrency("4-8");

return factory;

}

@Bean

MessageConverter converter(){

return new SimpleMessageConverter();

}

}

SalesMessage类

public class SalesMessage implements Serializable{

List sales = new ArrayList();

int messageType;

//getters/setters/toString()

销售课程

public class Sale implements Serializable{

private String product_type;

private Long value;

//getters/setters/toString()

发送消息

@Component

public class MyMessageSender {

@Autowired

private ConnectionFactory connectionFactory;

private JmsTemplate jmsTemplate;

@PostConstruct

public void init() {

this.jmsTemplate = new JmsTemplate(connectionFactory);

}

public void sendMessage(String message) {

System.out.println("sending: " + message);

jmsTemplate.send(AppConfig.QUEUE_NAME, new MessageCreator() {

@Override

public Message createMessage(Session session) throws JMSException {

return session.createTextMessage(message);

}

});

}

}

***编辑了Spring Config updqted

@Configuration

@ComponentScan

@EnableJms

public class AppConfig {

public static final String QUEUE_NAME = "example.queue";

@Bean

public ConnectionFactory connectionFactory() {

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");

return connectionFactory;

}

@Bean

public JmsListenerContainerFactory jmsListenerContainerFactory() {

DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();

factory.setConnectionFactory(connectionFactory());

// core poll size=4 threads and max poll size 8 threads

factory.setConcurrency("4-8");

return factory;

}

@Bean

public MessageConverter jacksonJmsMessageConverter() {

MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();

converter.setTargetType(MessageType.TEXT);

converter.setTypeIdPropertyName("_type");

return converter;

}

@Bean

public JmsTemplate jmsTemplate() {

JmsTemplate template = new JmsTemplate();

template.setMessageConverter(jacksonJmsMessageConverter());

template.setConnectionFactory(connectionFactory());

return template;

}

***编辑当我在Listener一侧打印消息时,我得到了

received:ActiveMQObjectMessage {commandId = 5,responseRequired = true,messageId = ID:win10-cha-51561-1509914170598-4:2:1:1:1,originalDestination = null,originalTransactionId = null,producerId = ID:win10-cha -51561-1509914170598-4:2:1:1,destination = queue://example.queue,transactionId = null,expiration = 0,timestamp = 1509914232995,arrival = 0,brokerInTime = 1509914232995,brokerOutTime = 1509914233010,correlationId = null ,replyTo = null,persistent = true,type = null,priority = 4,groupID = null,groupSequence = 0,targetConsumerId = null,compressed = false,userID = null,content = org.apache.activemq.util.ByteSequence@24f339bf ,marshalledProperties = null,dataStructure = null,redeliveryCounter = 0,size = 1346,properties = null,readOnlyProperties = true,readOnlyBody = true,droppable = false,jmsXGroupFirstForConsumer = false}

和SalesMessage salesMessage =(SalesMessage)messageConverter.fromMessage(message)引发此异常

org.springframework.jms.support.converter.MessageConversionException:无法在目标[queue:]上找到消息[ID:win10-cha-51561-1509914170598-4:2:1:1:1]的类型id属性[_type] //example.queue]

在发送方面,我打印消息

SalesMessage [sales=[Sale [product_type=product_type, value=1]], messageType=1]

并且,这是我更新的完整应用程序配置(我按照提供的建议)

@Configuration

@ComponentScan

@EnableJms

public class AppConfig {

public static final String QUEUE_NAME = "example.queue";

@Bean

public ConnectionFactory connectionFactory() {

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");

return connectionFactory;

}

@Bean

public JmsListenerContainerFactory jmsListenerContainerFactory() {

DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();

factory.setConnectionFactory(connectionFactory());

factory.setConcurrency("4-8");

factory.setMessageConverter(jacksonJmsMessageConverter());

return factory;

}

@Bean

public MessageConverter jacksonJmsMessageConverter() {

MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();

converter.setTargetType(MessageType.TEXT);

converter.setTypeIdPropertyName("_type");

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

converter.setObjectMapper(objectMapper);

return converter;

}

}

并且,这是我在最后一个建议之后发送消息的方式(重大更改是从jmsTemplate.send到jmsTemplate.convertAndSend):

@Component

public class MyMessageSender {

@Autowired

private ConnectionFactory connectionFactory;

private JmsTemplate jmsTemplate;

@PostConstruct

public void init() {

this.jmsTemplate = new JmsTemplate(connectionFactory);

}

public void sendMessage(SalesMessage message) {

System.out.println("sending: " + message);

jmsTemplate.convertAndSend(AppConfig.QUEUE_NAME, message);

}

}

***编辑

p6P5F.png

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐