Synchronous Message send and receive using JMS template and Spring Boot

空扰寡人 提交于 2019-12-13 03:24:31

问题


I am after sending/receiving call to JMS queue synchronously using JMS Template and Spring boot. I went through official spring doc for JMS template but of no help.

I am not too sure about calling receive() method specifically or it will automatically receive message once send() is invoked. Since this is synchronous call I only need to receive message that I've sent (with the correlation Id).

Any help in this regard would be appreciated. Please let me know if you need any further info.

Update!!

Below is my spring boot code.

JMSSConfig.java

@Configuration
@EnableJms
public class JMSConfig {

    @Bean
    public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        // This provides all boot's default to this factory, including the message converter

        configurer.configure(factory, connectionFactory);
        // You could still override some of Boot's default if necessary.
        return factory;
    }

    @Bean
    public MarshallingMessageConverter createMarshallingMessageConverter(final Jaxb2Marshaller jaxb2Marshaller) {
        System.out.println("executing createMarshallingMessageConverter");
        return new MarshallingMessageConverter(jaxb2Marshaller);

    }

    @Bean
    public Jaxb2Marshaller createJaxb2Marshaller(@Value("${context.path}") final String contextPath, @Value("${schema.location}") final String schemaLocaation) {
        System.out.println("executing Jaxb2Marshaller");
        Resource schemaResource = new ClassPathResource(schemaLocaation);
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setContextPath(contextPath);
        jaxb2Marshaller.setSchema(schemaResource);
        Map<String, Object> properties = new HashMap<>();
        properties.put(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        jaxb2Marshaller.setMarshallerProperties(properties);

        return jaxb2Marshaller;
    }



}

Sender and receiver code

@Component
public class Receiver {

    @Autowired
    JmsTemplate jmsTemplate;

     @JmsListener(destination = "mailbox", containerFactory="myFactory")
    public void receiveMessage(CacheMsgType submitEventType) {
        System.out.println("Received <" + submitEventType + ">");
    }

    public void send(CacheMsgType submitEventType) {
         jmsTemplate.convertAndSend("mailbox", submitEventType);
         System.out.println("Successfully sent a message.");
    }

 }

JAXB Generated classes

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SubmitEventType", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", propOrder = {
    "eventType",
    "clientApplication",
    "clientReferenceID",
    "systemDate",
    "transactionAcceptTime",
    "bsb",
    "accountNumber",
    "productcode",
    "accttypecode",
    "trancode",
    "meid",
    "baiCode",
    "baiDecs",
    "tranamount",
    "amountonhold",
    "recordedlimit",
    "currentbalance",
    "availablebalance",
    "description",
    "reference",
    "payer"
})
public class SubmitEventType {

    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String eventType;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String clientApplication;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String clientReferenceID;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String systemDate;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String transactionAcceptTime;
    @XmlElement(name = "BSB", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String bsb;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String accountNumber;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String productcode;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String accttypecode;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String trancode;
    @XmlElement(name = "MEID", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String meid;
    @XmlElement(name = "BAICode", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String baiCode;
    @XmlElement(name = "BAIDecs", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String baiDecs;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String tranamount;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String amountonhold;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String recordedlimit;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String currentbalance;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String availablebalance;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String description;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String reference;
    @XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected String payer;

    /**
     * Gets the value of the eventType property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getEventType() {
        return eventType;
    }

    /**
     * Sets the value of the eventType property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setEventType(String value) {
        this.eventType = value;
    }

    /**
     * Gets the value of the clientApplication property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getClientApplication() {
        return clientApplication;
    }

    /**
     * Sets the value of the clientApplication property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setClientApplication(String value) {
        this.clientApplication = value;
    }

    /**
     * Gets the value of the clientReferenceID property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getClientReferenceID() {
        return clientReferenceID;
    }

    /**
     * Sets the value of the clientReferenceID property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setClientReferenceID(String value) {
        this.clientReferenceID = value;
    }

    /**
     * Gets the value of the systemDate property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getSystemDate() {
        return systemDate;
    }

    /**
     * Sets the value of the systemDate property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setSystemDate(String value) {
        this.systemDate = value;
    }

    /**
     * Gets the value of the transactionAcceptTime property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getTransactionAcceptTime() {
        return transactionAcceptTime;
    }

    /**
     * Sets the value of the transactionAcceptTime property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setTransactionAcceptTime(String value) {
        this.transactionAcceptTime = value;
    }

    /**
     * Gets the value of the bsb property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getBSB() {
        return bsb;
    }

    /**
     * Sets the value of the bsb property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setBSB(String value) {
        this.bsb = value;
    }

    /**
     * Gets the value of the accountNumber property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getAccountNumber() {
        return accountNumber;
    }

    /**
     * Sets the value of the accountNumber property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setAccountNumber(String value) {
        this.accountNumber = value;
    }

    /**
     * Gets the value of the productcode property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getProductcode() {
        return productcode;
    }

    /**
     * Sets the value of the productcode property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setProductcode(String value) {
        this.productcode = value;
    }

    /**
     * Gets the value of the accttypecode property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getAccttypecode() {
        return accttypecode;
    }

    /**
     * Sets the value of the accttypecode property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setAccttypecode(String value) {
        this.accttypecode = value;
    }

    /**
     * Gets the value of the trancode property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getTrancode() {
        return trancode;
    }

    /**
     * Sets the value of the trancode property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setTrancode(String value) {
        this.trancode = value;
    }

    /**
     * Gets the value of the meid property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getMEID() {
        return meid;
    }

    /**
     * Sets the value of the meid property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setMEID(String value) {
        this.meid = value;
    }

    /**
     * Gets the value of the baiCode property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getBAICode() {
        return baiCode;
    }

    /**
     * Sets the value of the baiCode property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setBAICode(String value) {
        this.baiCode = value;
    }

    /**
     * Gets the value of the baiDecs property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getBAIDecs() {
        return baiDecs;
    }

    /**
     * Sets the value of the baiDecs property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setBAIDecs(String value) {
        this.baiDecs = value;
    }

    /**
     * Gets the value of the tranamount property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getTranamount() {
        return tranamount;
    }

    /**
     * Sets the value of the tranamount property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setTranamount(String value) {
        this.tranamount = value;
    }

    /**
     * Gets the value of the amountonhold property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getAmountonhold() {
        return amountonhold;
    }

    /**
     * Sets the value of the amountonhold property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setAmountonhold(String value) {
        this.amountonhold = value;
    }

    /**
     * Gets the value of the recordedlimit property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getRecordedlimit() {
        return recordedlimit;
    }

    /**
     * Sets the value of the recordedlimit property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setRecordedlimit(String value) {
        this.recordedlimit = value;
    }

    /**
     * Gets the value of the currentbalance property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getCurrentbalance() {
        return currentbalance;
    }

    /**
     * Sets the value of the currentbalance property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setCurrentbalance(String value) {
        this.currentbalance = value;
    }

    /**
     * Gets the value of the availablebalance property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getAvailablebalance() {
        return availablebalance;
    }

    /**
     * Sets the value of the availablebalance property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setAvailablebalance(String value) {
        this.availablebalance = value;
    }

    /**
     * Gets the value of the description property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getDescription() {
        return description;
    }

    /**
     * Sets the value of the description property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setDescription(String value) {
        this.description = value;
    }


    public String getReference() {
        return reference;
    }


    public void setReference(String value) {
        this.reference = value;
    }


    public String getPayer() {
        return payer;
    }


    public void setPayer(String value) {
        this.payer = value;
    }

}

CashMsgType.java

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "CacheMsg", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CacheMsgType", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", propOrder = {
    "submitEvent"
})
public class CacheMsgType {

    @XmlElement(name = "SubmitEvent", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
    protected List<SubmitEventType> submitEvent;


    public List<SubmitEventType> getSubmitEvent() {
        if (submitEvent == null) {
            submitEvent = new ArrayList<SubmitEventType>();
        }
        return this.submitEvent;
    }

}

It seems sending on to mailbox queue is working but receiving gives error

Exception

2018-05-05 10:44:53.280 WARN 4120 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer : Execution of JMS message listener failed, and no ErrorHandler has been set.

org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message Endpoint handler details: Method [public void com.nab.services.mq.Receiver.receiveMessage(com.nab.services.dto.CacheMsgType)] Bean [com.nab.services.mq.Receiver@134bfc8] ; nested exception is org.springframework.messaging.converter.MessageConversionException: Cannot convert from [javax.xml.bind.JAXBElement] to [com.nab.services.dto.CacheMsgType] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@3621aa, failedMessage=org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@3621aa at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_162] Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [javax.xml.bind.JAXBElement] to [com.nab.services.dto.CacheMsgType] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@3621aa at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:144) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:116) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:137) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:109) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE] ... 10 common frames omitted


回答1:


This might be implementation specific, but once the message is sent, you should be able to read the message id from the message itself.



来源:https://stackoverflow.com/questions/50146057/synchronous-message-send-and-receive-using-jms-template-and-spring-boot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!