0

我是一名开发人员,在拥有大约 5 年的 .NET 经验后重返 Java。虽然我了解 MVC 框架,但我对 Spring MVC 和 Spring 框架完全陌生。

我有一个任务,我打算将实体保存在 activemq JMS 队列上。在发送更复杂的对象之前,我决定先用一个简单的 TextMessage 进行尝试。每次我尝试从映射到视图上的输入按钮控件的控制器发送时,我都会在 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) WebAppConfig.java,其中完成了 Spring IoC 管道。这个类代替了 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

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

@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?我怎样才能得到这个工作?非常感谢你。

4

1 回答 1

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 进行设置。

于 2014-12-21T14:13:25.337 回答