无法使用Spring的JmsTemplate将JMS消息发送到activemq队列

时间:2014-12-21 14:04:16

标签: java spring spring-mvc activemq jmstemplate

我是一名开发人员,在大约5年的.NET经验之后回归Java。虽然我对MVC框架有所了解,但我对Spring MVC和spring框架都是全新的。

我有一项任务,我打算在activemq JMS队列上保存实体。在发送更复杂的对象之前,我决定首先使用简单的TextMessage进行尝试。每次我尝试从映射到视图上的输入按钮控件的Controller发送时,我在Tomcat中得到一个java.lang.NullPointerException。除此之外,它没有向我显示太多信息。它只显示我的来源是ApiMessageSender类中的这行代码。

jmsTemplate.send(new MessageCreator(){  

        @Override  
        public Message createMessage(Session session) throws JMSException {  
            return session.createTextMessage(message);  
        }  
    });  

spring web mvc Web应用程序中的实现由三个类组成。 1)ApiMessageSender.java

import javax.jms.*;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.jms.core.JmsTemplate;  
import org.springframework.jms.core.MessageCreator;  
import org.springframework.stereotype.Component;  

@Component("messageSender")  
public class ApiMessageSender {  
@Autowired  
private JmsTemplate jmsTemplate;  
public void sendMessage(final String message){  
    jmsTemplate.send(new MessageCreator(){  

        @Override  
        public Message createMessage(Session session) throws JMSException {  
            return session.createTextMessage(message);  
        }  
    });  
}  
}  

2)完成Spring IoC管道的WebAppConfig.java。此类代替ApplicationContext.xml文件,该文件在此项目中根本不使用。在执行应用程序之前,从ActiveMQ管理Web界面手动创建了队列名称。

@Bean
    public org.apache.activemq.ActiveMQConnectionFactory connectionFactory() {
        org.apache.activemq.ActiveMQConnectionFactory connectionFactory = new org.apache.activemq.ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL("tcp://localhost:61616");
        return connectionFactory;
    }

    @Bean
    public org.springframework.jms.core.JmsTemplate jmsTemplate() {
        org.springframework.jms.core.JmsTemplate jmsTemplate = new org.springframework.jms.core.JmsTemplate(connectionFactory());
        jmsTemplate.setDefaultDestinationName("apiqueue");
        return jmsTemplate;
    }

3)ApiController.java

在View上单击按钮时调用的控制器中的此操作方法。我已经注释了特定的代码片段,以便我可以继续其他要求。

@RequestMapping(value="/create", method=RequestMethod.POST)
    public ModelAndView createNewApi(@ModelAttribute @Valid Api api,
            BindingResult result,
            final RedirectAttributes redirectAttributes) {

        if (result.hasErrors())
            return new ModelAndView("api-new");

        ModelAndView mav = new ModelAndView();
        String message = "New api "+api.getApiKey()+" was successfully created.";

        apiService.create(api);

        //Send object to Queue.
        /*GenericXmlApplicationContext ctx=new GenericXmlApplicationContext();  
        ctx.load("classpath:applicationContext.xml");  
        ctx.refresh();*/  

       /* ApiMessageSender sender = new ApiMessageSender();  
        sender.sendMessage("hello jms3");*/
        //ctx.close();
        //End of messaging task. The message should be successfully in the JMS Queue.

        mav.setViewName("redirect:/api/list.html");

        redirectAttributes.addFlashAttribute("message", message);   
        return mav;     
    }

这可能是什么问题?为什么我在这里得到java.lang.NullPointerException?我怎样才能使这个工作? 非常感谢你。

1 个答案:

答案 0 :(得分:1)

如果没有完整的堆栈跟踪,很难完全告诉您,但根据已注释掉的代码,您的问题可能是您正在使用“ApiMessageSender sender = new ApiMessageSender();”实例化你的ApiMessageSender。通过这样做,您的jmsTemplate将永远不会自动装配,因为您没有使用Spring来实例化您的bean。所以我最好的猜测(没有发布堆栈跟踪)是当你的代码调用jmsTemplate.send时它会得到一个空指针,因为jmsTemplate从未设置过。

执行此操作的正确方法是使用SpringDispatcherServlet设置Spring MVC上下文并启动Bean。然后你可以将你的ApiMessageSender自动装入你的控制器类,而不是调用“new ApiMessageSender()”

请查看此处的文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html

您不需要直接在控制器方法中引用应用程序上下文。应该通过web.xml文件使用Spring设置所有内容。