org.springframework.messaging.support

## Class MessageHeaderAccessor

- java.lang.Object
- - org.springframework.messaging.support.MessageHeaderAccessor

- Direct Known Subclasses:
    NativeMessageHeaderAccessor

      public class MessageHeaderAccessor
      extends Object

  Wrapper around `MessageHeaders` that provides extra features such as strongly typed accessors for specific headers, the ability to leave headers in a `Message` mutable, and the option to suppress automatic generation of `id` and `timestamp` headers. Subclasses such as `NativeMessageHeaderAccessor` and others provide support for managing processing vs external source headers as well as protocol specific headers.

  Below is a workflow to initialize headers via `MessageHeaderAccessor`, or one of its subclasses, then create a `Message`, and then re-obtain the accessor possibly from a different component:

       // Create a message with headers
       MessageHeaderAccessor accessor = new MessageHeaderAccessor();
       accessor.setHeader("foo", "bar");
       MessageHeaders headers = accessor.getMessageHeaders();
       Message message = MessageBuilder.createMessage("payload", headers);

       // Later on
       MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message);
       Assert.notNull(accessor, "No MessageHeaderAccessor");

  In order for the above to work, all participating components must use `MessageHeaders` to create, access, or modify headers, or otherwise `getAccessor(Message, Class)` will return null. Below is a workflow that shows how headers are created and left mutable, then modified possibly by a different component, and finally made immutable perhaps before the possibility of being accessed on a different thread:

       // Create a message with mutable headers
       MessageHeaderAccessor accessor = new MessageHeaderAccessor();
       accessor.setHeader("foo", "bar");
       accessor.setLeaveMutable(true);
       MessageHeaders headers = accessor.getMessageHeaders();
       Message message = MessageBuilder.createMessage("payload", headers);

       // Later on
       MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message);
       if (accessor.isMutable()) {
           // It's mutable, just change the headers
           accessor.setHeader("bar", "baz");
       }
       else {
           // It's not, so get a mutable copy, change and re-create
           accessor = MessageHeaderAccessor.getMutableAccessor(message);
           accessor.setHeader("bar", "baz");
           accessor.setLeaveMutable(true); // leave mutable again or not?
           message = MessageBuilder.createMessage(message.getPayload(), accessor);
       }

       // Make the accessor immutable
       MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message);
       accessor.setImmutable();

  Since:
    4.0
  Author:
    Rossen Stoyanchev, Juergen Hoeller

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static Charset` | `DEFAULT_CHARSET` The default charset used for headers.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `MessageHeaderAccessor()` A constructor to create new headers.
    `MessageHeaderAccessor(Message<?> message)` A constructor accepting the headers of an existing message to copy.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `copyHeaders(Map<String,?> headersToCopy)` Copy the name-value pairs from the provided Map.
    `void` | `copyHeadersIfAbsent(Map<String,?> headersToCopy)` Copy the name-value pairs from the provided Map.
    `protected MessageHeaderAccessor` | `createAccessor(Message<?> message)` Build a 'nested' accessor for the given message.
    `static MessageHeaderAccessor` | `getAccessor(Message<?> message)` Return the original `MessageHeaderAccessor` used to create the headers of the given `Message`, or `null` if that's not available or if its type does not match the required type.
    `static <T extends MessageHeaderAccessor> T` | `getAccessor(Message<?> message, Class<T> requiredType)` Return the original `MessageHeaderAccessor` used to create the headers of the given `Message`, or `null` if that's not available or if its type does not match the required type.
    `static <T extends MessageHeaderAccessor> T` | `getAccessor(MessageHeaders messageHeaders, Class<T> requiredType)` A variation of `getAccessor(org.springframework.messaging.Message, Class)` with a `MessageHeaders` instance instead of a `Message`.
    `MimeType` | `getContentType()`
    `String` | `getDetailedLogMessage(Object payload)` Return a more detailed message for logging purposes.
    `protected String` | `getDetailedPayloadLogMessage(Object payload)`
    `Object` | `getErrorChannel()`
    `Object` | `getHeader(String headerName)` Retrieve the value for the header with the given name.
    `UUID` | `getId()`
    `MessageHeaders` | `getMessageHeaders()` Return the underlying `MessageHeaders` instance.
    `static MessageHeaderAccessor` | `getMutableAccessor(Message<?> message)` Return a mutable `MessageHeaderAccessor` for the given message attempting to match the type of accessor used to create the message headers, or otherwise wrapping the message with a `MessageHeaderAccessor` instance.
    `Object` | `getReplyChannel()`
    `String` | `getShortLogMessage(Object payload)` Return a concise message for logging purposes.
    `protected String` | `getShortPayloadLogMessage(Object payload)`
    `Long` | `getTimestamp()`
    `boolean` | `isModified()` Check whether the underlying message headers have been marked as modified.
    `boolean` | `isMutable()` Whether the underlying headers can still be modified.
    `protected boolean` | `isReadableContentType()`
    `protected boolean` | `isReadOnly(String headerName)`
    `void` | `removeHeader(String headerName)` Remove the value for the given header name.
    `void` | `removeHeaders(String... headerPatterns)` Removes all headers provided via array of 'headerPatterns'.
    `void` | `setContentType(MimeType contentType)`
    `void` | `setErrorChannel(MessageChannel errorChannel)`
    `void` | `setErrorChannelName(String errorChannelName)`
    `void` | `setHeader(String name, Object value)` Set the value for the given header name.
    `void` | `setHeaderIfAbsent(String name, Object value)` Set the value for the given header name only if the header name is not already associated with a value.
    `void` | `setImmutable()` By default, when `getMessageHeaders()` is called, `"this"` `MessageHeaderAccessor` instance can no longer be used to modify the underlying message headers.
    `void` | `setLeaveMutable(boolean leaveMutable)` By default, when `getMessageHeaders()` is called, `"this"` `MessageHeaderAccessor` instance can no longer be used to modify the underlying message headers and the returned `MessageHeaders` is immutable.
    `protected void` | `setModified(boolean modified)` Mark the underlying message headers as modified.
    `void` | `setReplyChannel(MessageChannel replyChannel)`
    `void` | `setReplyChannelName(String replyChannelName)`
    `Map<String,Object>` | `toMap()` Return a copy of the underlying header values as a plain `Map` object.
    `MessageHeaders` | `toMessageHeaders()` Return a copy of the underlying header values as a `MessageHeaders` object.
    `String` | `toString()`
    `protected void` | `verifyType(String headerName, Object headerValue)`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### DEFAULT_CHARSET

          public static final Charset DEFAULT_CHARSET

      The default charset used for headers.

  - ### Constructor Detail

    - #### MessageHeaderAccessor

          public MessageHeaderAccessor()

      A constructor to create new headers.

    - #### MessageHeaderAccessor

          public MessageHeaderAccessor(@Nullable
                                       Message<?> message)

      A constructor accepting the headers of an existing message to copy.
      Parameters:
        `message` - a message to copy the headers from, or `null` if none

  - ### Method Detail

    - #### createAccessor

          protected MessageHeaderAccessor createAccessor(Message<?> message)

      Build a 'nested' accessor for the given message.
      Parameters:
        `message` - the message to build a new accessor for
      Returns:
        the nested accessor (typically a specific subclass)

    - #### setLeaveMutable

          public void setLeaveMutable(boolean leaveMutable)

      By default, when `getMessageHeaders()` is called, `"this"` `MessageHeaderAccessor` instance can no longer be used to modify the underlying message headers and the returned `MessageHeaders` is immutable.

      However when this is set to `true`, the returned (underlying) `MessageHeaders` instance remains mutable. To make further modifications continue to use the same accessor instance or re-obtain it via:
      `MessageHeaderAccessor.getAccessor(Message, Class)`

      When modifications are complete use `setImmutable()` to prevent further changes. The intended use case for this mechanism is initialization of a Message within a single thread.

      By default this is set to `false`.

      Since:
        4.1

    - #### setImmutable

          public void setImmutable()

      By default, when `getMessageHeaders()` is called, `"this"` `MessageHeaderAccessor` instance can no longer be used to modify the underlying message headers. However if `setLeaveMutable(boolean)` is used, this method is necessary to indicate explicitly when the `MessageHeaders` instance should no longer be modified.
      Since:
        4.1

    - #### isMutable

          public boolean isMutable()

      Whether the underlying headers can still be modified.
      Since:
        4.1

    - #### setModified

          protected void setModified(boolean modified)

      Mark the underlying message headers as modified.
      Parameters:
        `modified` - typically `true`, or `false` to reset the flag
      Since:
        4.1

    - #### isModified

          public boolean isModified()

      Check whether the underlying message headers have been marked as modified.
      Returns:
        `true` if the flag has been set, `false` otherwise

    - #### getMessageHeaders

          public MessageHeaders getMessageHeaders()

      Return the underlying `MessageHeaders` instance.

      Unless `setLeaveMutable(boolean)` was set to `true`, after this call, the headers are immutable and this accessor can no longer modify them.

      This method always returns the same `MessageHeaders` instance if invoked multiples times. To obtain a copy of the underlying headers, use `toMessageHeaders()` or `toMap()` instead.

      Since:
        4.1

    - #### toMessageHeaders

          public MessageHeaders toMessageHeaders()

      Return a copy of the underlying header values as a `MessageHeaders` object.

      This method can be invoked many times, with modifications in between where each new call returns a fresh copy of the current header values.

      Since:
        4.1

    - #### toMap

          public Map<String,Object> toMap()

      Return a copy of the underlying header values as a plain `Map` object.

      This method can be invoked many times, with modifications in between where each new call returns a fresh copy of the current header values.

    - #### getHeader

          @Nullable
          public Object getHeader(String headerName)

      Retrieve the value for the header with the given name.
      Parameters:
        `headerName` - the name of the header
      Returns:
        the associated value, or `null` if none found

    - #### setHeader

          public void setHeader(String name,
                                @Nullable
                                Object value)

      Set the value for the given header name.

      If the provided value is `null`, the header will be removed.

    - #### verifyType

          protected void verifyType(@Nullable
                                    String headerName,
                                    @Nullable
                                    Object headerValue)

    - #### setHeaderIfAbsent

          public void setHeaderIfAbsent(String name,
                                        Object value)

      Set the value for the given header name only if the header name is not already associated with a value.

    - #### removeHeader

          public void removeHeader(String headerName)

      Remove the value for the given header name.

    - #### removeHeaders

          public void removeHeaders(String... headerPatterns)

      Removes all headers provided via array of 'headerPatterns'.

      As the name suggests, array may contain simple matching patterns for header names. Supported pattern styles are: "xxx*", "*xxx", "*xxx*" and "xxx*yyy".

    - #### copyHeaders

          public void copyHeaders(@Nullable
                                  Map<String,?> headersToCopy)

      Copy the name-value pairs from the provided Map.

      This operation will overwrite any existing values. Use `copyHeadersIfAbsent(Map)` to avoid overwriting values.

    - #### copyHeadersIfAbsent

          public void copyHeadersIfAbsent(@Nullable
                                          Map<String,?> headersToCopy)

      Copy the name-value pairs from the provided Map.

      This operation will not overwrite any existing values.

    - #### isReadOnly

          protected boolean isReadOnly(String headerName)

    - #### getId

          @Nullable
          public UUID getId()

    - #### getTimestamp

          @Nullable
          public Long getTimestamp()

    - #### setContentType

          public void setContentType(MimeType contentType)

    - #### getContentType

          @Nullable
          public MimeType getContentType()

    - #### setReplyChannelName

          public void setReplyChannelName(String replyChannelName)

    - #### setReplyChannel

          public void setReplyChannel(MessageChannel replyChannel)

    - #### getReplyChannel

          @Nullable
          public Object getReplyChannel()

    - #### setErrorChannelName

          public void setErrorChannelName(String errorChannelName)

    - #### setErrorChannel

          public void setErrorChannel(MessageChannel errorChannel)

    - #### getErrorChannel

          @Nullable
          public Object getErrorChannel()

    - #### getShortLogMessage

          public String getShortLogMessage(Object payload)

      Return a concise message for logging purposes.
      Parameters:
        `payload` - the payload that corresponds to the headers.
      Returns:
        the message

    - #### getDetailedLogMessage

          public String getDetailedLogMessage(@Nullable
                                              Object payload)

      Return a more detailed message for logging purposes.
      Parameters:
        `payload` - the payload that corresponds to the headers.
      Returns:
        the message

    - #### getShortPayloadLogMessage

          protected String getShortPayloadLogMessage(Object payload)

    - #### getDetailedPayloadLogMessage

          protected String getDetailedPayloadLogMessage(@Nullable
                                                        Object payload)

    - #### isReadableContentType

          protected boolean isReadableContentType()

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `Object`

    - #### getAccessor

          @Nullable
          public static MessageHeaderAccessor getAccessor(Message<?> message)

      Return the original `MessageHeaderAccessor` used to create the headers of the given `Message`, or `null` if that's not available or if its type does not match the required type.

      This is for cases where the existence of an accessor is strongly expected (followed up with an assertion) or where an accessor will be created otherwise.

      Parameters:
        `message` - the message to get an accessor for
      Returns:
        an accessor instance of the specified type, or `null` if none
      Since:
        5.1.19

    - #### getAccessor

          @Nullable
          public static <T extends MessageHeaderAccessor> T getAccessor(Message<?> message,
                                                                                  @Nullable
                                                                                  Class<T> requiredType)

      Return the original `MessageHeaderAccessor` used to create the headers of the given `Message`, or `null` if that's not available or if its type does not match the required type.

      This is for cases where the existence of an accessor is strongly expected (followed up with an assertion) or where an accessor will be created otherwise.

      Parameters:
        `message` - the message to get an accessor for
        `requiredType` - the required accessor type (or `null` for any)
      Returns:
        an accessor instance of the specified type, or `null` if none
      Since:
        4.1

    - #### getAccessor

          @Nullable
          public static <T extends MessageHeaderAccessor> T getAccessor(MessageHeaders messageHeaders,
                                                                                  @Nullable
                                                                                  Class<T> requiredType)

      A variation of `getAccessor(org.springframework.messaging.Message, Class)` with a `MessageHeaders` instance instead of a `Message`.

      This is for cases when a full message may not have been created yet.

      Parameters:
        `messageHeaders` - the message headers to get an accessor for
        `requiredType` - the required accessor type (or `null` for any)
      Returns:
        an accessor instance of the specified type, or `null` if none
      Since:
        4.1

    - #### getMutableAccessor

          public static MessageHeaderAccessor getMutableAccessor(Message<?> message)

      Return a mutable `MessageHeaderAccessor` for the given message attempting to match the type of accessor used to create the message headers, or otherwise wrapping the message with a `MessageHeaderAccessor` instance.

      This is for cases where a header needs to be updated in generic code while preserving the accessor type for downstream processing.

      Returns:
        an accessor of the required type (never `null`)
      Since:
        4.1