org.springframework.messaging.support

Class MessageHeaderAccessor

  • java.lang.Object
    • org.springframework.messaging.support.MessageHeaderAccessor
  • Direct Known Subclasses:
    NativeMessageHeaderAccessor


    public class MessageHeaderAccessor
    extends java.lang.Object
    A base for classes providing strongly typed getters and setters as well as behavior around specific categories of headers (e.g. STOMP headers). Supports creating new headers, modifying existing headers (when still mutable), or copying and modifying existing headers.

    The method getMessageHeaders() provides access to the underlying, fully-prepared MessageHeaders that can then be used as-is (i.e. without copying) to create a single message as follows:

     MessageHeaderAccessor accessor = new MessageHeaderAccessor();
     accessor.setHeader("foo", "bar");
     Message message = MessageBuilder.createMessage("payload", accessor.getMessageHeaders());
     

    After the above, by default the MessageHeaderAccessor becomes immutable. However it is possible to leave it mutable for further initialization in the same thread, for example:

     MessageHeaderAccessor accessor = new MessageHeaderAccessor();
     accessor.setHeader("foo", "bar");
     accessor.setLeaveMutable(true);
     Message message = MessageBuilder.createMessage("payload", accessor.getMessageHeaders());
    
     // later on in the same thread...
    
     MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message);
     accessor.setHeader("bar", "baz");
     accessor.setImmutable();
     

    The method toMap() returns a copy of the underlying headers. It can be used to prepare multiple messages from the same MessageHeaderAccessor instance:

     MessageHeaderAccessor accessor = new MessageHeaderAccessor();
     MessageBuilder builder = MessageBuilder.withPayload("payload").setHeaders(accessor);
    
     accessor.setHeader("foo", "bar1");
     Message message1 = builder.build();
    
     accessor.setHeader("foo", "bar2");
     Message message2 = builder.build();
    
     accessor.setHeader("foo", "bar3");
     Message  message3 = builder.build();
     

    However note that with the above style, the header accessor is shared and cannot be re-obtained later on. Alternatively it is also possible to create one MessageHeaderAccessor per message:

     MessageHeaderAccessor accessor1 = new MessageHeaderAccessor();
     accessor.set("foo", "bar1");
     Message message1 = MessageBuilder.createMessage("payload", accessor1.getMessageHeaders());
    
     MessageHeaderAccessor accessor2 = new MessageHeaderAccessor();
     accessor.set("foo", "bar2");
     Message message2 = MessageBuilder.createMessage("payload", accessor2.getMessageHeaders());
    
     MessageHeaderAccessor accessor3 = new MessageHeaderAccessor();
     accessor.set("foo", "bar3");
     Message message3 = MessageBuilder.createMessage("payload", accessor3.getMessageHeaders());
     

    Note that the above examples aim to demonstrate the general idea of using header accessors. The most likely usage however is through subclasses.

    Since:
    4.0
    Author:
    Rossen Stoyanchev, Juergen Hoeller
    • Field Detail

      • DEFAULT_CHARSET

        public static final java.nio.charset.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 java.util.Map<java.lang.String,java.lang.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 java.lang.Object getHeader(java.lang.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(java.lang.String name,
                              @Nullable
                              java.lang.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
                                  java.lang.String headerName,
                                  @Nullable
                                  java.lang.Object headerValue)
      • setHeaderIfAbsent

        public void setHeaderIfAbsent(java.lang.String name,
                                      java.lang.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(java.lang.String headerName)
        Remove the value for the given header name.
      • removeHeaders

        public void removeHeaders(java.lang.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
                                java.util.Map<java.lang.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
                                        java.util.Map<java.lang.String,?> headersToCopy)
        Copy the name-value pairs from the provided Map.

        This operation will not overwrite any existing values.

      • isReadOnly

        protected boolean isReadOnly(java.lang.String headerName)
      • getId

        @Nullable
        public java.util.UUID getId()
      • getTimestamp

        @Nullable
        public java.lang.Long getTimestamp()
      • setContentType

        public void setContentType(MimeType contentType)
      • setReplyChannelName

        public void setReplyChannelName(java.lang.String replyChannelName)
      • setReplyChannel

        public void setReplyChannel(MessageChannel replyChannel)
      • getReplyChannel

        @Nullable
        public java.lang.Object getReplyChannel()
      • setErrorChannelName

        public void setErrorChannelName(java.lang.String errorChannelName)
      • setErrorChannel

        public void setErrorChannel(MessageChannel errorChannel)
      • getErrorChannel

        @Nullable
        public java.lang.Object getErrorChannel()
      • getShortLogMessage

        public java.lang.String getShortLogMessage(java.lang.Object payload)
        Return a concise message for logging purposes.
        Parameters:
        payload - the payload that corresponds to the headers.
        Returns:
        the message
      • getDetailedLogMessage

        public java.lang.String getDetailedLogMessage(@Nullable
                                                      java.lang.Object payload)
        Return a more detailed message for logging purposes.
        Parameters:
        payload - the payload that corresponds to the headers.
        Returns:
        the message
      • getShortPayloadLogMessage

        protected java.lang.String getShortPayloadLogMessage(java.lang.Object payload)
      • getDetailedPayloadLogMessage

        protected java.lang.String getDetailedPayloadLogMessage(@Nullable
                                                                java.lang.Object payload)
      • isReadableContentType

        protected boolean isReadableContentType()
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • getAccessor

        @Nullable
        public static <T extends MessageHeaderAccessor> T getAccessor(Message<?> message,
                                                                                @Nullable
                                                                                java.lang.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
                                                                                java.lang.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