Я после отправки / получения вызова в очередь JMS синхронно с использованием JMS Template и Spring boot. Я прошел официальный весенний документ для шаблона JMS, но не помог.
Я не слишком уверен в конкретном вызове метода receive (), иначе он автоматически получит сообщение после вызова send (). Поскольку это синхронный вызов, мне нужно только получить отправленное сообщение (с идентификатором корреляции).
Любая помощь в этом отношении будет принята с благодарностью. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.
Обновление !!
Ниже мой весенний загрузочный код.
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;
}
}
Код отправителя и получателя
@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 Сгенерированные классы
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;
}
}
Кажется, отправка в очередь почтовых ящиков работает, но при получении выдается ошибка
Исключение
2018-05-05 10: 44: 53.280 WARN 4120 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer: сбой при выполнении прослушивателя сообщений JMS, и не был установлен ErrorHandler.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: метод прослушивателя не может быть вызван с входящим сообщением
Детали обработчика конечной точки:
Метод [public void com.nab.services.mq.Receiver.receiveMessage (com.nab.services.dto.CacheMsgType)]
Бин [com.nab.services.mq.Receiver@134bfc8]
; вложенным исключением является org.springframework.messaging.converter.MessageConversionException: невозможно преобразовать из [javax.xml.bind.JAXBElement] в [com.nab.services.dto.CacheMsgType] для org.springframework.jms.lMessageLtable.aptable $. 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]Вызывается: org.springframework.messaging.converter.MessageConversionException: Невозможно преобразовать из [javax.xml.bind.JAXBElement] в [com.nab.services.dto.CacheMsgType] для org.springframework.jms.listener.Adap $. MessagingMessageConverterAdapter $ LazyResolutionMessage @ 3621aa
в 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.ELE
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues (InvocableHandlerMethod.java:137) ~ [spring-messaging-5.0.5.RELEASE.jar: 5.0.5.RELEASE]
в 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 общих кадров пропущено