【问题标题】:JMS outbound channel adapter converting to byte[]JMS 出站通道适配器转换为 byte[]
【发布时间】:2014-09-15 19:00:10
【问题描述】:

我使用下面的配置来发送带有对象负载的 JMS 消息(比如说 HelloWorld 对象),但是当我使用消息驱动的适配器接收消息时,负载被转换为字节 []。

有没有办法防止这种情况发生?我看到出站适配器最终调用 SimpleMessageConverter 方法`createMessageForSerializable --> session.createObjectMessage(object)

<si:chain input-channel="errorChannelIn"> 
  <si:router 
       expression="headers.jms_redelivered.equals(T(java.lang.Boolean).FALSE) ? 'errorQueueChannel' : 'channel2Name' " 
       apply-sequence="true"> 
     <si:mapping value="errorQueueChannel" channel="errorChannel"/> 
     <si:mapping value="channel2Name" channel="channel2"/> 
  </si:router> 
</si:chain> 

<si-jms:outbound-channel-adapter id="errorQueueMessageSender"
                                 channel="errorChannel"
                                 connection-factory="connectionFactory" session-transacted="true" destination="errorQueue"
        />

但是,当我使用 JmsTemplate 发送消息时,它完美地将消息作为 messageObject 发送,并且消息驱动的适配器将对象作为有效负载。代码如下:sn-p。

知道我哪里出错了。

jmsTemplate.send(new MessageCreator() {
        @Override
        public Message createMessage(Session session) throws JMSException {
            return session.createObjectMessage(messageObject);
        }
    });

【问题讨论】:

    标签: spring spring-integration


    【解决方案1】:

    我猜你是指&lt;si-jms:outbound-channel-adapter&gt; 上的extract-payload="false"

    在这种情况下,&lt;si-jms:message-driven-channel-adapter&gt; 将工作委托给org.springframework.jms.support.converter.SimpleMessageConverter,最终得到:

    else if (message instanceof ObjectMessage) {
        return extractSerializableFromMessage((ObjectMessage) message);
    }
    

    然后你会反序列化Message&lt;?&gt;

    更新

    抱歉,目前还不清楚发生了什么。刚刚使用我们的Samples 进行了测试。在那里您可以找到服务器/客户端配置:outboundChannelAdapter.xmlinboundChannelAdapter.xml。我在GatewayDemoTest 中添加了一个测试用例:

    private final static String[] configFilesChannelAdapterDemo = {
            "/META-INF/spring/integration/common.xml",
            "/META-INF/spring/integration/inboundChannelAdapter.xml",
            "/META-INF/spring/integration/outboundChannelAdapter.xml"
    };
    
    @Test
    public void testAdapterDemo() throws InterruptedException {
    
        System.setProperty("spring.profiles.active", "testCase");
    
        final GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext(configFilesChannelAdapterDemo);
    
        final MessageChannel stdinToJmsoutChannel = applicationContext.getBean("stdinToJmsoutChannel", MessageChannel.class);
    
        Foo foo = new Foo("bar");
    
        stdinToJmsoutChannel.send(MessageBuilder.withPayload(foo).build());
    
        final QueueChannel queueChannel = applicationContext.getBean("queueChannel", QueueChannel.class);
    
        Message<?> reply = queueChannel.receive(20000);
        Assert.assertNotNull(reply);
        Object out = reply.getPayload();
    
        Assert.assertThat(out, Matchers.instanceOf(Foo.class));
    
        Assert.assertEquals(foo, out);
    
        applicationContext.close();
    }
    
    public static class Foo implements Serializable {
    
        private final String bar;
    
        public Foo(String bar) {
            this.bar = bar;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            Foo foo = (Foo) o;
    
            return !(bar != null ? !bar.equals(foo.bar) : foo.bar != null);
    
        }
    
        @Override
        public int hashCode() {
            return bar != null ? bar.hashCode() : 0;
        }
    
    }
    

    如你所见,我将一些 Serializable 对象放入队列,&lt;jms:message-driven-channel-adapter&gt; 为我接收到完全相同的反序列化对象。

    也许您的问题出现在 &lt;jms:outbound-channel-adapter&gt; 之前的某个地方,您可以在其中使用 &lt;payload-serializing-transformer&gt;

    您介意在&lt;jms:message-driven-channel-adapter&gt; 之前重新检查payload,或者甚至在SimpleMessageConverter.toMessage 上设置断点吗?

    【讨论】:

    • 不,我尝试了 extract-payload="false" 和 true 两者,但是当我发送带有对象有效负载的消息时没有工作。我有一个 A 类对象作为出站通道适配器的有效负载,这是我期望的有效负载,当消息驱动的适配器从队列而不是字节 [] 使用消息时我的第一条消息。如果不清楚,将在原始问题中添加更多细节。谢谢
    • 添加了测试用例和一些解释
    • 谢谢阿特姆。我确实有断点,并且可以看到,当使用jms:outbound-channel-adapter 将有效负载作为对象(例如foo)将消息放入队列时,我将其作为对象,正如我在SimpleMessageConverter.toMessage 中看到的那样,但在Object fromMessage(Message message) 时为字节[]我会继续调试
    • 那么,您是否想说JmsTemplateObjectMessage 发送它,但&lt;si-jms:outbound-channel-adapter&gt;BytesMessage 发送?
    • 是的。在此之前我有一条链&lt;si:chain input-channel="errorChannelIn"&gt; &lt;si:router expression="headers.jms_redelivered.equals(T(java.lang.Boolean).FALSE) ? 'errorQueueChannel' : 'channel2Name' " apply-sequence="true"&gt; &lt;si:mapping value="errorQueue" channel="errorChannel"/&gt; &lt;si:mapping value="channel2Name" channel="channel2"/&gt; &lt;/si:router&gt; &lt;/si:chain&gt;
    猜你喜欢
    • 2016-07-19
    • 2015-03-10
    • 1970-01-01
    • 2015-11-26
    • 2015-05-01
    • 2018-07-06
    • 2011-08-29
    • 2016-05-28
    • 2014-10-23
    相关资源
    最近更新 更多