Announcement Announcement Module
No announcement yet.
Message Headers - Why are they so sticky? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Message Headers - Why are they so sticky?

    This is probably a stupid question, but I'm having some trouble understanding how message headers are handled by the framework when passing between different end points. I have for example a service activator that takes an incoming message, does some processing and returns a new Message using MessageBuilder.withPayload(payload).build().

    I would expect that the downstream message would not contain all the headers from the original message, but it seems the framework re-attaches all the headers. This is also the case for splitters and transformers. What is the reasoning behind re-attaching the message headers even though I'm explicitly returning a new message without them?

    Any insights would be appreciated.


  • #2
    First, it's generally not recommended to tie your application to the framework by exposing Message<?> to it; it's better to use POJOs as much as possible and use <header-enricher/> and <header-filter/> elements instead.

    That said, there are cases where applications need to receive and return Message<?> because they want to consolidate multiple functions into a single method (transform the payload, change headers etc). It's a bit of an anti-pattern (mixing concerns like that), but sometimes pragmatism wins over purism.

    There are a number of headers that are critical to the performance of the framework and so, yes, in many cases (service activator, splitter, bridge, etc, etc), the framework will copy headers from the inbound message to the outbound message.

    However, the headers are NOT copied for filters or transformers that return Message<?>; the framework assumes that components of these types "know what they are doing" and have full control over the message.

    (I can probably point you to many forum posts where this has "burned" other users because they lost important framework headers when improperly constructing these components).

    This is all controlled by AbstractReplyProducingMessageHandler.shouldCopyReq uestHeaders() which returns true by default but is overridden to false in MessageTransformingHandler and MessageFilter.

    Hope that helps.


    • #3
      Hi Gary,
      That's very helpful. From a purist point of view I can see the benefit in making the SI config more verbose, using additional <filter />, <header-filter /> and <header-enricher /> elements. In this case I'm defering to multiple services within my service activator in order to persist the payload and some headers. I then only want to return the original payload with all of the headers stripped out. I could use a <header-filter /> as you suggested, but in this case there's really no way for me to know what all the headers are in advance. There are multiple upstream flows coming into this channel.

      Thanks for the tip on AbstractReplyProducingMessageHandler that's exactly what I was looking for.