2016-05-12 15 views
1

Ich habe eine Feder-Service, der @ JmsListener-Methode hat. Es wird von einem Client aufgerufen, der eine Nachricht über JmsMessagingTemplate.convertSendAndReceive() sendet. Das funktioniert gut.Mit einem @ JmsListener sendAndReceive verarbeiten und senden Sie einfach

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

Ich bin attemptign für nur tun, einen convertSend Anruf auf dem Client-Funktionalität zu implementieren. Das heißt, der Client sendet und vergisst und wartet nicht auf eine Antwort. Ich habe einen solchen Anruf gemacht, und es ist auf der Serverseite

jmsMessagingTemplate.convertAndSend(myDestination, myObj); 

Aber verarbeitet bekam, habe ich einen Fehler auf der Server-Seite angibt, dass die Anforderungsnachricht enthält keine Antwort an-Ziel. Das macht für mich einen Sinn, weil ich über die jmsMessageTemplate keinen Aufruf der Methode "receive" mache. Aber ich bin mir nicht sicher, was ich dagegen tun soll. Ist es möglich, eine andere JmsListener-Methode für das gleiche Ziel zu haben, aber die Anfragen "send without reply" zu behandeln, oder muss ich ein separates Ziel und ActiveMQQueue erstellen? Grundsätzlich möchte ich, dass mein Server/JMS-Listener keine Antwort zurücksenden kann, wenn dies nicht notwendig ist.

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 [[email protected], 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 

Antwort

2

können Sie zwei @JmsListener s verwenden und die selector Eigenschaft, die verschiedenen Nachrichtentypen für jeden Zuhörer zu lenken.

Dazu muss der Absender eine Nachrichteneigenschaft festlegen, die dann im Selektorausdruck verwendet wird.

Es ist ein bisschen komplizierter ist, wenn die Messaging-Vorlage verwenden, weil Sie eine neue Nachricht zu bauen, aber mit dem Grunde JmsTemplate:

jmsTemplate.convertSendAndReceive(dest, object, messagePostProcessor); 

wo messagePostProcessor ein Verfahren

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

Dann requiresReply=yes/no hat verwenden im Selektor.

Wenn Sie die Besetzung vermeiden und die Nachrichtenvorlage verwenden möchten, müssen Sie MessageBuilder.fromMessage(message).setHeader(...).build() in der (anderen) MessagePostProcessor) verwenden. In diesem Fall ist es ein Spring-Messaging Message kein JMS Message.

EDIT

Sie wirklich, wenn auch nicht irgendetwas davon benötigen, wenn Sie Ihre Zuhörer aus den Daten sagen kann, ob eine Antwort erwartet wird und gibt einfach null für Nachrichten, die eine Antwort nicht brauchen.

+0

OK, ich schaute auf MessagePostProcessor, aber ich dachte, es war eine Methode, eine Antwort asynhronously zu erhalten. Der MessagePostProcessor wird vor dem Senden von JMS? Dies scheint vielversprechend. –

+0

Ja; Es ist ein Mechanismus, mit dem Sie die von der Konvertierung erstellte JMS-Nachricht ändern können, bevor sie an JMS gesendet wird. –

+0

OK, es sieht so aus, als ob die angegebene convertSendAndReceive nicht existiert. Ich denke, ich muss den Zielklassentyp angeben. –