2010-03-22 41 views
5

Tôi đã đấu tranh với nhiệm vụ "đơn giản" này cho nhiều người hết hạn hơn, tôi bị kẹt trong 2 ngày nay cần được trợ giúp. Tôi đã thay đổi những thứ arround như zillion lần bây giờ, cuối cùng tôi stumbled khi this spring JMS tutorial.Thực hiện nhắn tin JMS

Điều tôi muốn làm, Gửi tin nhắn và nhận tin nhắn. Tôi cũng đã đọc this book chương 8 về nhắn tin. Nó thực sự độc đáo giải thích 2 loại tin nhắn và có ví dụ tốt đẹp cho publish-and-subscribe loại nhưng bây giờ ví dụ cho point-to-point nhắn tin (đây là một trong những tôi cần).

Tôi có thể gửi thông điệp tới hàng đợi trên của riêng tôi, nhưng không có một đầu mối làm thế nào để nhận thats tại sao tôi đã cố gắng với mùa xuân hướng dẫn này ở đây là những gì tôi đã có cho đến nay:

RE-EDITED SENDER:

package quartz.spring.com.example; 

import java.util.HashMap; 
import java.util.Map; 

import javax.jms.ConnectionFactory; 
import javax.jms.Destination; 
import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.Queue; 
import javax.jms.Session; 

import org.springframework.jms.core.MessageCreator; 
import org.springframework.jms.core.JmsTemplate; 
import org.springframework.jms.core.JmsTemplate102; 
import org.springframework.jms.core.MessagePostProcessor; 

public class JmsQueueSender { 

    private JmsTemplate jmsTemplate; 
    private Destination destination; 

    public void setConnectionFactory(ConnectionFactory cf) { 
     this.jmsTemplate = new JmsTemplate102(cf, false); 
    } 

    public void setQueue(Queue queue) { 
     this.destination = queue; 
    } 

    public void simpleSend() { 
     this.jmsTemplate.send(this.destination, new MessageCreator() { 
      public Message createMessage(Session session) throws JMSException { 
       return session.createTextMessage("hello queue world"); 
      } 
     }); 
    } 

    public void sendWithConversion() { 
     Map map = new HashMap(); 
     map.put("Name", "Mark"); 
     map.put("Age", new Integer(47)); 
     jmsTemplate.convertAndSend("ReceiverQueue", map, new MessagePostProcessor() { 
      public Message postProcessMessage(Message message) throws JMSException { 
       message.setIntProperty("AccountID", 1234); 
       message.setJMSCorrelationID("123-00001"); 
       return message; 
      } 
     }); 
    } 
} 

RECEIVER:

package quartz.spring.com.example; 

import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.MessageListener; 
import javax.jms.TextMessage; 

public class ExampleListener implements MessageListener { 

    public void onMessage(Message message) { 
     if (message instanceof TextMessage) { 
      try { 
       System.out.println(((TextMessage) message).getText()); 
      } 
      catch (JMSException ex) { 
       throw new RuntimeException(ex); 
      } 
     } 
     else { 
      throw new IllegalArgumentException("Message must be of type TextMessage"); 
     } 
    } 
} 

biên tập lại applicationcontext.xml

 <?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
     http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"> 

    <bean id="sender" class="quartz.spring.com.example.JmsQueueSender" 
     init-method="sendWithConversion" /> 
    <bean id="receiver" class="quartz.spring.com.example.ExampleListener"> 
    </bean> 

    <bean id="jmsContainer" 
     class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
     <property name="connectionFactory" ref="connectionFactory" /> 
     <property name="destination" ref="queueDestination" /> 
     <property name="messageListener" ref="messageListener" /> 
    </bean> 

    <!-- Queue configuration --> 
    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
     <property name="environment"> 
      <props> 
       <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop> 
       <prop key="java.naming.provider.url">jnp://localhost:1099</prop> 
       <prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop> 
       <prop key="java.naming.security.principal">admin</prop> 
       <prop key="java.naming.security.credentials">admin</prop> 
      </props> 
     </property> 
    </bean> 

    <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
     <property name="jndiTemplate" ref="jndiTemplate" /> 
     <property name="jndiName" value="ConnectionFactory" /> 
    </bean> 

    <bean id="queueDestination" class="org.springframework.jndi.JndiObjectFactoryBean"> 
     <property name="jndiTemplate" ref="jndiTemplate" /> 
     <property name="jndiName"> 
      <value>queue/ReceiverQueue</value> 
     </property> 
    </bean> 
</beans> 

thực sự không biết rằng đường cong học tập cho điều này là quá lâu, tôi có nghĩa là ý tưởng rất đơn giản:

  1. Gửi thông điệp tới hàng đợi đến
  2. nhận thông điệp từ hàng đợi đến

Để nhận tin nhắn, bạn thực hiện như sau (vì vậy không cuốn sách nói):

1 Locate a ConnectionFactory, typically using JNDI. 
2 Use the ConnectionFactory to create a Connection. 
3 Use the Connection to create a Session. 
4 Locate a Destination, typically using JNDI. 
5 Use the Session to create a MessageConsumer for that Destination. 

Một khi bạn đã làm điều này, các phương pháp trên MessageConsumer cho phép bạn hoặc truy vấn Destination cho các thông điệp hoặc để đăng ký thông báo tin nhắn.

Ai đó có thể hướng dẫn tôi đi đúng hướng, có hướng dẫn giải thích chi tiết cách nhận tin nhắn từ hàng đợi không? Tôi có mã thông báo đang hoạt động, không đăng bài ở đây vì bài đăng này cũng vậy miễn là nó được. EDIT:

Tôi đã thêm vào dịch vụ đích nhắn tin jboss của mình.xml MBean này:

<mbean code="org.jboss.jms.server.destination.QueueService" 
    name="jboss.messaging.destination:service=Queue,name=ReceiverQueue" 
    xmbean-dd="xmdesc/Queue-xmbean.xml"> 
    <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends> 
    <depends>jboss.messaging:service=PostOffice</depends> 
    </mbean> 
+0

Tôi nghĩ bạn đang thực hiện nhắn tin PTP, nhưng đây là tin nhắn không đồng bộ mà bạn đang thực hiện. –

+0

Vâng tôi muốn thực hiện điểm đến điểm nhưng rõ ràng là tôi không nhận được ở đó –

+0

Bây giờ bạn dường như có một bean được gọi là bộ nhận và một bean được gọi là messageListener, cả hai người nghe :) – extraneon

Trả lời

3

Từ URL mùa xuân ví dụ của bạn, bạn quên:

<!-- and this is the message listener container --> 
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    <property name="connectionFactory" ref="connectionFactory"/> 
    <property name="destination" ref="destination"/> 
    <property name="messageListener" ref="messageListener" /> 
</bean> 

nào kết nối hàng đợi cho người nghe :)

EDIT

Bạn đã viết trong nhận xét:

but still I'm getting this error : org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sender' defined in ServletContext resource [/WEB-INF/conf/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException 

How does Example listener knows which queue to listen to anyways, I didn't specify to it, didn't know how 

Vấn đề đầu tiên là tôi nghĩ rằng một NullPointerException trên dòng jmsTemplate.convertAndSend. JmsTemplate của bạn chưa được khởi tạo.

Tôi tin rằng đó là vì phương thức init không phải là convertAndSend. Bạn không nên cần một phương pháp init nào cả. Bạn nên thiết lập các thuộc tính trong applicationcontext.xml, về vậy:

<bean id="sender" class="quartz.spring.com.example.JmsQueueSender"> 
    <property name="queue" value="theNameOfYourQueue"> <!-- or in stead of value ref to a String which contains the shared queue name --> 
    <property name="connectionFactory" ref="connectionFactory"/> 
</bean> 

Điều đó sẽ sửa chữa các lỗi trong khi gửi (BTW tại sao bạn sử dụng JMSTemplate102 và không JMSTemplate?).

Câu hỏi khác, bạn định cấu hình tên hàng đợi bằng cách đặt thuộc tính trên hạt. Trong trường hợp này bạn dường như đang nghe hàng đợi queueDestination/ReceiverQueue vì jmsContainer của bạn được cấu hình để xử lý các cuộc gọi trên hàng đợi đó bởi người nghe của bạn.

Nơi heck đã làm là bean messageListener được định nghĩa trong applicationcontext.xml?

nếu bạn sử dụng ref="someName" ở đâu đó cũng phải có một <bean name="someName" ở đâu đó.

EDIT

cũng có một cái nhìn tại this example mà dường như có một mã chút cấu hình giải thích. pubSubDomain là sai nghĩa là nó là điểm-điểm. :)

+0

@extraneon không chỉ là điều tôi quên rõ ràng còn có thêm một số thứ nữa, tôi cập nhật người gửi, appcontext và thêm mbean vào dịch vụ đích –

Các vấn đề liên quan