Spring Messaging JMS答复拦截器

时间:2018-06-28 17:31:23

标签: spring spring-boot spring-jms spring-messaging

我有一个@JmsListener方法,该方法接收一个参数并返回一个对象实例,所有这些实例都使用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标头,即,我想在“中间件”中进行设置(在我的配置中进行设置)。

我必须走哪条路?看来Spring的JmsListener支持类无法配置到该级别。

1 个答案:

答案 0 :(得分:0)

有一个:

/**
 * @see AbstractMessageListenerContainer#setMessageConverter(MessageConverter)
 */
public void setMessageConverter(MessageConverter messageConverter) {
    this.messageConverter = messageConverter;
}

您可以在AbstractJmsListenerContainerFactory上提供。实际上,由于您使用Spring Boot,因此只需要在应用程序上下文中提供这样的@Bean

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并设置其属性和标头。

更新

我不知道您的要求中缺少什么,但是在这里我是怎么看的:

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

}

关于此事的测试案例:

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

}