我试图使用mappingjackson2messageconvertor
将java对象转换为json格式,但看起来它不是转换为json对象,而是抛出空点异常错误。想知道我做错了什么。
我检查了这里的一个例子。但我不使用rabbitmq,而不是我使用activemq。
@SpringBootApplication
@EnableJms
public class Application {
@Bean
JmsListenerContainerFactory<?> myJmsContainerFactory(ConnectionFactory connectionFactory) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new MappingJackson2MessageConverter());
return factory;
}
public static void main(String[] args) {
// Clean out any ActiveMQ data from a previous run
FileSystemUtils.deleteRecursively(new File("activemq-data"));
// Launch the application
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
AssetApi asset = new AssetApi();
asset.setBroadcasterId("test");
asset.setNotes("test");
// Send a message
MessageCreator messageCreator = new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
MessageConverter message = new MappingJackson2MessageConverter();
return message.toMessage(asset, session);
}
};
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
System.out.println("Sending a new message.");
jmsTemplate.send("mailbox-destination", messageCreator);
}
}
错误java.lang.NullPointerException: null
at org.apache.activemq.command.ActiveMQMessage.getStringProperty(ActiveMQMessage.java:676)
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.getJavaTypeForMessage(MappingJackson2MessageConverter.java:377)
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.fromMessage(MappingJackson2MessageConverter.java:195)
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:215)
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter.extractPayload(AbstractAdaptableMessageListener.java:397)
at org.springframework.jms.support.converter.MessagingMessageConverter.fromMessage(MessagingMessageConverter.java:108)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.toMessagingMessage(MessagingMessageListenerAdapter.java:77)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:62)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:678)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:638)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:608)
at org.springframework.jms.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:579)
at org.springframework.jms.listener.SimpleMessageListenerContainer.processMessage(SimpleMessageListenerContainer.java:329)
at org.springframework.jms.listener.SimpleMessageListenerContainer$2.onMessage(SimpleMessageListenerContainer.java:305)
at org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1390)
at org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:131)
at org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:202)
at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:133)
at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:48)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
@SpringBootApplication
@EnableJms
public class Application {
@Bean
JmsListenerContainerFactory<?> myJmsContainerFactory(ConnectionFactory connectionFactory) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new MappingJackson2MessageConverter());
return factory;
}
public static void main(String[] args) {
// Clean out any ActiveMQ data from a previous run
FileSystemUtils.deleteRecursively(new File("activemq-data"));
// Launch the application
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
AssetApi asset = new AssetApi();
asset.setBroadcasterId("test");
asset.setNotes("test");
// Send a message
MessageCreator messageCreator = new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
MessageConverter message = new MappingJackson2MessageConverter();
return message.toMessage(asset, session);
}
};
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
System.out.println("Sending a new message.");
jmsTemplate.send("mailbox-destination", messageCreator);
}
}
java.lang.NullPointerException: null
at org.apache.activemq.command.ActiveMQMessage.getStringProperty(ActiveMQMessage.java:676)
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.getJavaTypeForMessage(MappingJackson2MessageConverter.java:377)
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.fromMessage(MappingJackson2MessageConverter.java:195)
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:215)
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter.extractPayload(AbstractAdaptableMessageListener.java:397)
at org.springframework.jms.support.converter.MessagingMessageConverter.fromMessage(MessagingMessageConverter.java:108)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.toMessagingMessage(MessagingMessageListenerAdapter.java:77)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:62)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:678)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:638)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:608)
at org.springframework.jms.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:579)
at org.springframework.jms.listener.SimpleMessageListenerContainer.processMessage(SimpleMessageListenerContainer.java:329)
at org.springframework.jms.listener.SimpleMessageListenerContainer$2.onMessage(SimpleMessageListenerContainer.java:305)
at org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1390)
at org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:131)
at org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:202)
at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:133)
at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:48)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
对于JMS转换器,您需要告诉转换器您希望从JSON创建什么类型(id)。
您可以通过告诉它哪个JMS属性(头)包含类型id来实现。
从类型id到类名有一个Map
。
或者你可以子类化并覆盖getJavaTypeForMessage()
。
参见javadoc中转换器上的getJavaTypeForMessage()
方法
我做了Gary Russell指出的,从我的调用类
Map<String, Class<?>> typeIdMappings = new HashMap<String, Class<?>>();
typeIdMappings.put("JMSType",Audit.class);
mappingJackson2MessageConverter.setTypeIdMappings(typeIdMappings);
mappingJackson2MessageConverter.setTypeIdPropertyName("JMSType");
Audit audit = (Audit) mappingJackson2MessageConverter.fromMessage(message);
然后我重写了MappingJackson2MessageConverter的方法:
@Component
public class MecMappingJackson2MessageConverter extends MappingJackson2MessageConverter {
private Map<String, Class<?>> idClassMappings = new HashMap<String, Class<?>>();
private Map<Class<?>, String> classIdMappings = new HashMap<Class<?>, String>();
private ObjectMapper objectMapper = new ObjectMapper();
private ClassLoader beanClassLoader;
@Override
public JavaType getJavaTypeForMessage(Message message){
Class<?> mappedClass = this.idClassMappings.get("JMSType");
if (mappedClass != null) {
return this.objectMapper.getTypeFactory().constructType(mappedClass);
}
try {
Class<?> typeClass = ClassUtils.forName("JMSType", this.beanClassLoader);
return this.objectMapper.getTypeFactory().constructType(typeClass);
}
catch (Throwable ex) {
throw new MessageConversionException("Failed to resolve type id [" + "JMSType" + "]", ex);
}
}
@Override
public void setTypeIdMappings(Map<String, Class<?>> typeIdMappings) {
this.idClassMappings = new HashMap<String, Class<?>>();
for (Map.Entry<String, Class<?>> entry : typeIdMappings.entrySet()) {
String id = entry.getKey();
Class<?> clazz = entry.getValue();
this.idClassMappings.put(id, clazz);
this.classIdMappings.put(clazz, id);
}
}
}
我已经创建了自己的反序列化器,并在MappingJackson2MessageConverter对象中设置了相同的内容,如下所示
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(WebResponse.class,new WebResponseDeserializer());
mapper.registerModule(module);
new MappingJackson2MessageConverter().setObjectMapper(mapper);
WebResponseDeserializer扩展com.fasterxml.jackson. databindd . jsondeserializer以提供自定义的方式来解组json对象
您只需要在消息转换器上调用setTypeIdPropertyName
并为消息头传递所需的名称,其中消息转换器将保存pojo的类名