Spring 消息传递 JMS 回复拦截器
Spring Messaging JMS reply interceptor
我有一个接收参数的 @JmsListener 方法和 returns 一个 object 实例,所有这些都与 XML 和 JAXB 编组一起工作。
@JmsListener(
containerFactory = ...,
destination = ...,
selector = ...
)
public RunReport.Response run(RunReport runReport) throws Exception
{
// ...
RunReport.Response response = new RunReport.Response();
return response;
}
如我所愿,返回 RunReport.Response
而不是 Message<RunReport.Response>
。
但我想为所有 JmsListener 方法的回复注入 JMS headers,即,我想在 "middleware"(在我的配置中设置)中执行此操作。
我必须走什么路才能做到呢? Spring 的 JmsListener 支持 类 似乎无法配置到那个级别。
有这个:
/**
* @see AbstractMessageListenerContainer#setMessageConverter(MessageConverter)
*/
public void setMessageConverter(MessageConverter messageConverter) {
this.messageConverter = messageConverter;
}
就AbstractJmsListenerContainerFactory
你可以提供。实际上你只需要在应用程序上下文中提供这样一个 @Bean
因为你处理 Spring Boot.
这个调用来自 AbstractAdaptableMessageListener
:
/**
* Build a JMS message to be sent as response based on the given result object.
* @param session the JMS Session to operate on
* @param result the content of the message, as returned from the listener method
* @return the JMS {@code Message} (never {@code null})
* @throws JMSException if thrown by JMS API methods
* @see #setMessageConverter
*/
protected Message buildMessage(Session session, Object result) throws JMSException {
因此,这确实是一个您可以构建自己的 JMS Message
并设置其属性和 headers.
的地方
更新
我不知道您的要求中缺少什么,但我是这样看的:
@SpringBootApplication
public class So51088580Application {
public static void main(String[] args) {
SpringApplication.run(So51088580Application.class, args);
}
@Bean
public MessageConverter messageConverter() {
return new SimpleMessageConverter() {
@Override
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
Message message = super.toMessage(object, session);
message.setStringProperty("myProp", "bar");
return message;
}
};
}
@JmsListener(destination = "foo")
public String jmsHandle(String payload) {
return payload.toUpperCase();
}
}
关于此事test-case:
@RunWith(SpringRunner.class)
@SpringBootTest
public class So51088580ApplicationTests {
@Autowired
private JmsTemplate jmsTemplate;
@Test
public void testReplyWithProperty() throws JMSException {
Message message = this.jmsTemplate.sendAndReceive("foo", session -> session.createTextMessage("foo"));
assertThat(message).isInstanceOf(TextMessage.class);
TextMessage textMessage = (TextMessage) message;
assertThat(textMessage.getText()).isEqualTo("FOO");
assertThat(textMessage.getStringProperty("myProp")).isEqualTo("bar");
}
}
我有一个接收参数的 @JmsListener 方法和 returns 一个 object 实例,所有这些都与 XML 和 JAXB 编组一起工作。
@JmsListener(
containerFactory = ...,
destination = ...,
selector = ...
)
public RunReport.Response run(RunReport runReport) throws Exception
{
// ...
RunReport.Response response = new RunReport.Response();
return response;
}
如我所愿,返回 RunReport.Response
而不是 Message<RunReport.Response>
。
但我想为所有 JmsListener 方法的回复注入 JMS headers,即,我想在 "middleware"(在我的配置中设置)中执行此操作。
我必须走什么路才能做到呢? Spring 的 JmsListener 支持 类 似乎无法配置到那个级别。
有这个:
/**
* @see AbstractMessageListenerContainer#setMessageConverter(MessageConverter)
*/
public void setMessageConverter(MessageConverter messageConverter) {
this.messageConverter = messageConverter;
}
就AbstractJmsListenerContainerFactory
你可以提供。实际上你只需要在应用程序上下文中提供这样一个 @Bean
因为你处理 Spring Boot.
这个调用来自 AbstractAdaptableMessageListener
:
/**
* Build a JMS message to be sent as response based on the given result object.
* @param session the JMS Session to operate on
* @param result the content of the message, as returned from the listener method
* @return the JMS {@code Message} (never {@code null})
* @throws JMSException if thrown by JMS API methods
* @see #setMessageConverter
*/
protected Message buildMessage(Session session, Object result) throws JMSException {
因此,这确实是一个您可以构建自己的 JMS Message
并设置其属性和 headers.
更新
我不知道您的要求中缺少什么,但我是这样看的:
@SpringBootApplication
public class So51088580Application {
public static void main(String[] args) {
SpringApplication.run(So51088580Application.class, args);
}
@Bean
public MessageConverter messageConverter() {
return new SimpleMessageConverter() {
@Override
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
Message message = super.toMessage(object, session);
message.setStringProperty("myProp", "bar");
return message;
}
};
}
@JmsListener(destination = "foo")
public String jmsHandle(String payload) {
return payload.toUpperCase();
}
}
关于此事test-case:
@RunWith(SpringRunner.class)
@SpringBootTest
public class So51088580ApplicationTests {
@Autowired
private JmsTemplate jmsTemplate;
@Test
public void testReplyWithProperty() throws JMSException {
Message message = this.jmsTemplate.sendAndReceive("foo", session -> session.createTextMessage("foo"));
assertThat(message).isInstanceOf(TextMessage.class);
TextMessage textMessage = (TextMessage) message;
assertThat(textMessage.getText()).isEqualTo("FOO");
assertThat(textMessage.getStringProperty("myProp")).isEqualTo("bar");
}
}