【问题标题】:How to nest Spring JMS MessageConverters如何嵌套 Spring JMS MessageConverters
【发布时间】:2010-09-19 11:07:31
【问题描述】:

我想编写一个可以包装另一个 MessageConverter 的 MessageConverter 类。此 MessageConverter 将调用子转换器,假定它生成一个 TextMessage。它将获取有效负载并 GZIP 对其进行压缩,创建一个 BytesMessage,最终返回给发送者。

问题出在 fromMessage() 中。我可以将有效负载转换回字符串,但随后我想创建一个“虚拟”TextMessage 将字符串填充到然后传递给子 MessageConverter 的 fromMessage() 方法。在那里我碰壁了,因为我无法在没有 JMS 会话对象的情况下创建 TextMessage,而且似乎根本无法在这种情况下获得会话。

我可以创建额外的属性来将更多的东西连接到这个类,但看起来我什至无法轻松地从 JMSTemplate 对象获取会话,而且我无法想象我还需要什么.

我即将在此代码中创建一个私有 TextMessage 实现,只是为了为子 MessageConverter 包装一个字符串。该类将需要大量的虚拟方法来充实界面,所有这些输入都会让婴儿耶稣哭泣。

谁能提出更好的方法?

【问题讨论】:

    标签: java spring jms


    【解决方案1】:

    事实上,我确实做了其中之一:

        private static class FakeTextMessage implements TextMessage {
                public FakeTextMessage(Message m) { this.childMessage = m; }
                private String text;
                private Message childMessage;
                public void setText(String t) { this.text = t; }
                public String getText() { return this.text; }
    
                // All the rest of the methods are simply pass-through
                // implementations of the rest of the interface, handing off to the child message.
                public void acknowledge() throws JMSException { this.childMessage.acknowledge(); }
                public void clearBody() throws JMSException { this.childMessage.clearBody(); }
                public void clearProperties() throws JMSException { this.childMessage.clearProperties(); }
                public Enumeration getPropertyNames() throws JMSException { return this.childMessage.getPropertyNames(); }
                public boolean propertyExists(String pn) throws JMSException { return this.childMessage.propertyExists(pn); }
    
                // and so on and so on
        }
    

    让我渴望 Objective C。这怎么可能? :)

    【讨论】:

      【解决方案2】:

      您真的想将 MessageConverter 实例包装在其他 MessageConverter 实例中吗? MessageConverter 的全部意义在于将消息转换为其他内容(不是 JMS 消息)。它并不是真正设计为将它们链接起来(每一步都制作一个虚假的 JMS 消息)。

      为什么不直接介绍自己的界面

      interface MessageBodyConverter {
        /** return a converted body of the original message */
        Object convert(Object body, Message originalMessage);
      }
      

      然后您可以创建一个调用其中之一的 MessageConverter(然后可以嵌套任意深度)

      class MyMessageConverter implements MessageConverter {
        private final MessageBodyConverter converter;
      
        public Object fromMessage(Message message) {
          if (message instanceof ObjectMessage) {
             return converter.convert(objectMessage.getObject(), message);
          ...
        }
      }
      

      然后,您可以尽可能多地链接这些 MessageBodyConverter 对象 - 另外,您可以访问原始 JMS 消息(获取标头等),而不必尝试创建 Message 的伪(可能不符合 JMS)实现?

      【讨论】:

      • 我可以这样做,但关键是只需将 GZIP 压缩 MessageConverter 连接到位,就可以在运行时使 GZIP 压缩 JMS 消息体成为可选的。这让我不必在现有的 MessageConverter 中编写 if/then/else 代码。
      • 哦,如果我实现了 JMS TextMessage 接口,并且如果除了 setText() 和 getText() 之外的所有方法都传递到真正是 JMS 消息的东西,它怎么会 符合 JMS 标准?
      • 只要您将几乎所有的消息 API 委托给真正的 JMS 消息,您就可以了;但这听起来像是大量的工作,但价值却很小。例如为什么不添加您自己的支持链接的 API 而不必包装每条消息?
      • 在底层使用 gzip 的同时,您打算如何实现 TextMessage API?那么您是否不必将 TextMessage 附加到 ObjectMessage 上?顺便说一句,gzip 压缩通常是 JMS 提供者在幕后为您做的事情——ActiveMQ 肯定就是这种情况
      • 这个转换器从孩子那里获取一个TextMessage,gzip的主体并在它的位置发送一个BytesMessage。在返回的路上,它获取 BytesMessage,提取并解压缩正文,将原始消息与未压缩的内容一起包装在 FakeTextMessage 中并提供给孩子。
      猜你喜欢
      • 2017-11-03
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 2011-03-31
      • 2014-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多