Results 1 to 5 of 5

Thread: How to convert payload and headers on JMS outbound message?

  1. #1
    Join Date
    Aug 2004
    Location
    London, UK
    Posts
    339

    Default How to convert payload and headers on JMS outbound message?

    hi,

    We're trying to send a file via an si:channel which will be converted to a JMS message. We'd rather not use the s-i API's directly in our code. The following code/config works exactly as we'd like;

    Code:
    Message<byte[]> m = MessageBuilder.withPayload("this could be a real file".getBytes())
        .setHeader("file.name", "target/file/name.txt")
        .build();
            
    MessageChannel out = (MessageChannel) context.getBean("gw-out");
    out.send(m);
    Code:
    <si:channel id="gw-out"/>
    <jms:outbound-channel-adapter
        connection-factory="connectionFactory"
        channel="gw-out"        
        destination-name="queue.dataupload.new"/>
    In the above example, a JMS BytesMessage with an appropriate JMSProperty for the 'file.name' header is placed on the queue. So far, so good - the consumer on that queue gets exactly what it needs from the above setup.

    Now, when I try to further this by removing the dependencies on Spring API's, I create a gateway interface..
    Code:
    public interface Gateway {
        void send(Object o);
    }
    .. add the following XML snippet..
    Code:
    <si:gateway 
        id="gateway"
        service-interface="test.Gateway" 
        default-request-channel="gw-out"/>
    .. and begin to amend the client code..
    Code:
    Gateway g = (Gateway) context.getBean("gateway");
    Object o = ?? // what goes here to replace the Spring MessageBuilder above?
    g.send(o);
    What do I replace the MessageBuilder with?

    Cheers!
    Darren.


    NB:
    Even if I leave the MessageBuilder in place, but still use the gateway, I have a new problem in that the actual GenericMessage instance gets serialized through the gateway. No longer do I have a BytesMessage on my JMS queue with a JMSProperty set with the 'file.name' value.. I have an ObjectMessage and a classname that the consumer knows nothing about. This appears to contradict the current ref docs that suggest the payload should be extracted.. I may have read this bit wrong of course.
    Darren Davison.
    Public Key: 0xE855B3EA

  2. #2
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    For the line to replace the builder, you should be able to do something like this:
    Code:
    g.send("this could be a real file".getBytes(), "target/file/name.txt");
    Where the gateway's interface defines a method like this:
    Code:
    void send(byte[] payload, @Header("file.name") String fileName);
    Let me know if that works.

    (I might need a bit more clarification on the question in your NB)

  3. #3
    Join Date
    Aug 2004
    Location
    London, UK
    Posts
    339

    Default

    thanks for the quick reply Mark.

    Yes, your solution works, but I still have a Spring API in the code (the @Header annotation). Is this unavoidable? Any way, say, to pass a Map that will be treated as headers automagically?

    Cheers,
    Darren.
    Darren Davison.
    Public Key: 0xE855B3EA

  4. #4
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    You can use @Headers and a map:
    Code:
    void send(byte[] payload, @Headers Map headerMap);
    Yes, either annotation (@Header or @Headers) is going to introduce a Spring import. I guess we could consider auto-detecting 2 arguments where one is a Map and therefore headers. The only problem is that you could pass a Map payload as well (e.g. send(Map payload, Map headers)) in which case we would have to rely on the order, and that seems pretty ugly.

  5. #5
    Join Date
    Aug 2004
    Location
    London, UK
    Posts
    339

    Default

    yes, reflection's inability to access parameters by name curses us again

    No better in many ways than the solution you proposed, but an alternative might be to check a Map for a key named "payload", treating all other keys as headers.

    We'll go with the annotation for now I guess.

    Cheers!
    Darren.
    Darren Davison.
    Public Key: 0xE855B3EA

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •