gpt4 book ai didi

java - JMS 消息传递实现

转载 作者:搜寻专家 更新时间:2023-10-31 20:24:26 24 4
gpt4 key购买 nike

我一直在努力为更有经验的人完成这个“简单”的任务,我被困了 2 天现在需要帮助。我已经改变了无数次,最后我偶然发现了this spring JMS tutorial .

我想做的是,发送一条消息并接收它。我也一直在阅读 this book第 8 章消息传递。它很好地解释了 2 种消息传递类型,并且有一个很好的 publish-and-subscribe 类型示例,但现在是 point-to-point 消息传递示例(这是我需要的那个)。

我可以自己将消息发送到队列,但不知道如何接收这就是我尝试使用这个 Spring 教程的原因,这是我到目前为止所得到的:

重新编辑的发件人:

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

接收者:

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

重新编辑了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>

真的不知道学习曲线这么长,我的意思是这个想法很简单:

  1. 发送消息到目标队列
  2. 从目标队列接收消息

要接收消息,您需要执行以下操作(书上也是如此):

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.

Once you’ve done this, methods on the MessageConsumer enable you to either query the Destination for messages or to register for message notification.

有人可以指导我正确的方向吗,有没有详细解释如何从队列接收消息的教程?我有有效的发送消息代码,没有在这里发布,因为这篇文章太长了是。编辑:

我将这个 Mbean 添加到我的 jboss messaging destination-service.xml 中:

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

最佳答案

从您忘记的 Spring 示例 URL 中:

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

将队列连接到监听器:)

编辑

您在评论中写道:

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

第一个问题是我认为 jmsTemplate.convertAndSend 行出现 nullPointerException .您的 jmsTemplate 尚未初始化。

我相信这是因为初始化方法不是 convertAndSend。您根本不需要初始化方法。您应该在 applicationcontext.xml 中设置属性,大致如下:

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

这应该可以修复发送时的错误(顺便说一句,你为什么使用 JMSTemplate102 而不是 JMSTemplate?)。

另一个问题,您通过设置 bean 的属性来配置队列名称。在这种情况下,您似乎正在收听 queueDestination 队列/ReceiverQueue,因为您的 jmsContainer 配置为处理您的收听者对该队列的调用。

applicationcontext.xml 中定义的 messageListener bean 到底在哪里?

如果你使用 ref="someName"某处也应该有一个 <bean name="someName"某处。

编辑

也可以看看 this example这似乎有更多的配置代码解释。 pubSubDomain 为 false 意味着它是点对点的:)

关于java - JMS 消息传递实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2492560/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com