2010-03-22 24 views
5

He estado luchando con esta tarea "simple" para personas con más experiencia, estoy atrapado durante 2 días y ahora necesito ayuda. He cambiado las cosas alrededor de billones de veces, finalmente tropecé con this spring JMS tutorial.Implementación de mensajería JMS

Lo que quiero hacer, enviar un mensaje y recibirlo. También he estado leyendo this book capítulo 8 sobre mensajería. Realmente explica muy bien 2 tipos de mensajes y hay un buen ejemplo para el tipo publish-and-subscribe pero ahora ejemplo para point-to-point mensajes (este es el que necesito).

soy capaz de enviar mensaje a la cola por mi cuenta, pero no tienen ni idea de cómo recibir es por eso que he intentado con este tutorial de primavera aquí es lo que tengo hasta ahora:

reeditada remitente:

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; 
      } 
     }); 
    } 
} 

RECEPTOR:

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"); 
     } 
    } 
} 

re-editado 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> 

no sabía muy bien que la curva de aprendizaje para esto es tan largo, me refiero a la idea es muy simple:

  1. Enviar mensaje a la cola de destino
  2. recibir el mensaje de la cola de destino

Para recibir mensajes, hacer lo siguiente (por lo que dice el libro):

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. 

Una vez hecho esto, los métodos en los MessageConsumer le permiten a cualquiera consulta el destino de los mensajes o para registrarse para la notificación de mensajes.

Puede alguien por favor me dirigir hacia la dirección correcta, es que hay un tutorial que explica en detalle cómo recibir mensaje de la cola? Tengo el trabajo enviar código de mensaje, no publicar aquí porque este post es demasiado mientras sea. EDITAR:

He añadido a mi servicio de destino de mensajes jboss.xml este Mbean:

<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

Pensé que estás haciendo mensajes PTP, pero esto es un mensaje asíncrono que estás haciendo. –

+0

Bueno, quería implementar punto a punto, pero obviamente no estoy llegando –

+0

Ahora parece tener un bean llamado receptor y un bean llamado messageListener, ambos oyentes :) – extraneon

Respuesta

3

de su ejemplo de Primavera URL ha olvidado:

<!-- 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> 

que conecta la cola para el oyente :)

EDITAR

Usted escribió en el comentarios:

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 

y

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

El primer problema es que creo que una NullPointerException en la línea jmsTemplate.convertAndSend. Su jmsTemplate no se ha inicializado.

Creo que es porque el método init no es convertAndSend. No deberías necesitar un método init en absoluto. Debe establecer las propiedades en el applicationContext.xml, sobre manera:

<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> 

Eso debe corregir los errores al enviar (por cierto, ¿por qué se utiliza JMSTemplate102 y no JMSTemplate?).

La otra pregunta, usted configure los nombres de cola estableciendo propiedades en los beans. En este caso, parece que está escuchando la cola QueueDestination/ReceiverQueue, ya que su jmsContainer está configurado para manejar llamadas en esa cola por parte de su oyente.

¿Dónde diablos está el messageListener bean definido en el applicationcontext.xml?

si usa ref="someName" en alguna parte también debería haber un <bean name="someName" en alguna parte.

EDITAR

también echar un vistazo a this example que parece tener un código de poco más de configuración explicó. el pubSubDomain es falso significa que es punto a punto :)

+0

@extraneon que no era solo una cosa que olvidé aparentemente hay algo más que agregar, actualicé mi remitente, el contexto de la aplicación y agregué mbean al servicio de destino –

Cuestiones relacionadas