2014-12-21 3 views
0

Я разработчик, возвращающийся на Java через 5 лет опыта работы с .NET. Хотя я знаю структуру MVC, я совершенно новичок в Spring MVC и Spring Framework.Невозможно отправить сообщение JMS в очередь activemq с помощью Spring's JmsTemplate

У меня есть назначение, где я собирался сохранить объекты в очереди JMS activemq. Сначала я решил попробовать это с помощью простого TextMessage перед отправкой более сложного объекта. Каждый раз, когда я пытаюсь отправить с контроллера, сопоставленного с элементом управления кнопки ввода в представлении, я получаю исключение java.lang.NullPointerException в Tomcat. Это не показывает мне много информации, кроме этого. Это только показывает мне, что это источник из этой строки кода в классе ApiMessageSender.

jmsTemplate.send(new MessageCreator(){ 

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

Реализация в веб-приложении весеннего web-сайта mvc состоит из трех классов. 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 до запуска приложения.

@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? Как я могу заставить это работать? спасибо.

+0

Не могли бы вы отправить исключение stacktrace и пометить соответствующие строки. – Ralph

ответ

1

Без полной стекирования сложно полностью сказать вам наверняка, но на основе кода с комментариями ваша проблема, вероятно, в том, что вы используете «ApiMessageSender sender = new ApiMessageSender();» для создания вашего ApiMessageSender. Делая это, ваш jmsTemplate никогда не будет автообновлен, так как вы не используете Spring для создания экземпляров ваших компонентов. Таким образом, мое лучшее предположение (без отслеживания стека) заключается в том, что когда ваш код вызывает jmsTemplate.send, он получает нулевой указатель, потому что jmsTemplate никогда не был установлен.

Правильный способ сделать это - использовать SpringDispatcherServlet для настройки контекста Spring MVC и для запуска ваших компонентов. Тогда вы могли бы autowire вашего ApiMessageSender в класс контроллера вместо вызова «новый ApiMessageSender()»

Посмотрите на документации здесь: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html

Вы не должны ссылаться на контексте приложения непосредственно в методе контроллера , Все должно быть настроено с помощью Spring в файле web.xml.

+0

Здравствуйте, xraiderx, ваше предложение сработало. Я аннотировал ApiMessageSender как @Autowired и после выполнения приложения сообщение появилось в очереди. Я нажал на сообщение, чтобы увидеть, могу ли я увидеть его в текстовом формате, и ActiveMQ предоставил мне сообщение об ошибке «Исключение произошло при обработке этого запроса, проверьте журнал для получения дополнительной информации!». Сообщение все еще находится в очереди, но я не вижу его строки или текстового содержимого. Невозможно просмотреть эту информацию до тех пор, пока мы не вывезем сообщение из очереди? Большое спасибо. – sage