使用 @JmsListener 处理 sendAndReceive 并仅发送

问题描述 投票:0回答:1

我有一个带有 @JmsListener 方法的 Spring 服务。它由客户端通过 JmsMessagingTemplate.convertSendAndReceive() 发送消息来调用。这很好用。

@Service
public class JmsMessageProcessor {
    @JmsListener(destination = "myDestination")
    protected Message<MyResponseObj> handleRequest(final MyInputObj myObj) {
        return MessageBuilder.withPayload(processObj(myObj)).build();
    }

}

.

// client
 MyResponseObj response = jmsMessagingTemplate.convertSendAndReceive(myDestination, myObj,
                MyResponseObj.class);

我正在尝试在客户端上实现仅进行

convertSend
调用的功能。也就是说,客户端将发送并忘记,而不等待响应。我已经进行了这样的调用,并且它确实在服务器端得到了处理

 jmsMessagingTemplate.convertAndSend(myDestination, myObj);

但是,我在服务器端收到错误,表明请求消息不包含回复目的地。这对我来说很有意义,因为我没有通过 jmsMessageTemplate 进行“接收”方法调用。但是,我不知道该怎么办。是否可以为同一目标使用另一个 JmsListener 方法,但专门处理“发送而不回复”请求,或者我是否必须创建单独的目标和 JMS 队列?基本上,我希望我的服务器/jms 侦听器能够在不需要时不发回响应。

javax.jms.InvalidDestinationException: Cannot determine response destination: Request message does not contain reply-to destination, and no default response destination set.
org.springframework.jms.listener.adapter.ReplyFailureException: Failed to send reply with payload [GenericMessage [payload=MyResponseObj@51c082ec, headers={timestamp=1462996638601, id=41877e45-b220-a320-f07a-64f9d50d98ae}]]; nested exception is javax.jms.InvalidDestinationException: Cannot determine response destination: Request message does not contain reply-to destination, and no default response destination set.
        at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.handleResult(AbstractAdaptableMessageListener.java:249) ~[spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:68) ~[spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:721) ~[spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:681) [spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) [spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315) [spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) [spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) [spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) [spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) [spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at java.lang.Thread.run(Thread.java:745) [?:1.7.0_99]
Caused by: javax.jms.InvalidDestinationException: Cannot determine response destination: Request message does not contain reply-to destination, and no default response destination set.
        at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.getResponseDestination(AbstractAdaptableMessageListener.java:343) ~[spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.getResponseDestination(AbstractAdaptableMessageListener.java:316) ~[spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.handleResult(AbstractAdaptableMessageListener.java:245) ~[spring-jms-4.2.3.RELEASE.jar:4.2.3.RELEASE]
        ... 10 more
java jms spring-jms
1个回答
4
投票

您可以使用两个

@JmsListener
selector
属性将不同的消息类型定向到每个侦听器。

这需要发送者设置一个消息属性,然后在选择器表达式中使用该属性。

使用消息模板时有点复杂,因为您必须构建一条新消息,但使用基本的

JmsTemplate
:

jmsTemplate.convertSendAndReceive(dest, object, messagePostProcessor);

其中

messagePostProcessor
有一个方法

public Message postProcessMessage(Message message) {
    message.setStringProperty("requiresReply", "yes");
    return message;
}

然后在选择器中使用

requiresReply=yes/no

如果您想避免强制转换并使用消息模板,则需要在(不同的

MessageBuilder.fromMessage(message).setHeader(...).build()
)中使用
MessagePostProcessor
。在本例中,它是 spring 消息传递
Message
,而不是 JMS
Message

编辑

但是,如果您的侦听器可以从数据中判断是否需要回复,并且对于不需要回复的消息只需返回

null
,那么您确实不需要任何这些。

© www.soinside.com 2019 - 2024. All rights reserved.