public class MessageHeaderAccessor extends Object
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();
Modifier and Type | Field and Description |
---|---|
static Charset |
DEFAULT_CHARSET
The default charset used for headers.
|
Constructor and Description |
---|
MessageHeaderAccessor()
A constructor to create new headers.
|
MessageHeaderAccessor(Message<?> message)
A constructor accepting the headers of an existing message to copy.
|
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> |
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> |
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) |
public static final Charset DEFAULT_CHARSET
public MessageHeaderAccessor()
protected MessageHeaderAccessor createAccessor(Message<?> message)
message
- the message to build a new accessor forpublic void setLeaveMutable(boolean leaveMutable)
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
.
public void setImmutable()
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.public boolean isMutable()
protected void setModified(boolean modified)
modified
- typically true
, or false
to reset the flagpublic boolean isModified()
true
if the flag has been set, false
otherwisepublic MessageHeaders getMessageHeaders()
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.
public MessageHeaders toMessageHeaders()
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.
public Map<String,Object> toMap()
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.
@Nullable public Object getHeader(String headerName)
headerName
- the name of the headernull
if none foundpublic void setHeader(String name, @Nullable Object value)
If the provided value is null
, the header will be removed.
public void setHeaderIfAbsent(String name, Object value)
public void removeHeader(String headerName)
public void removeHeaders(String... headerPatterns)
As the name suggests, array may contain simple matching patterns for header names. Supported pattern styles are: "xxx*", "*xxx", "*xxx*" and "xxx*yyy".
public void copyHeaders(@Nullable Map<String,?> headersToCopy)
This operation will overwrite any existing values. Use
copyHeadersIfAbsent(Map)
to avoid overwriting values.
public void copyHeadersIfAbsent(@Nullable Map<String,?> headersToCopy)
This operation will not overwrite any existing values.
protected boolean isReadOnly(String headerName)
public void setContentType(MimeType contentType)
public void setReplyChannelName(String replyChannelName)
public void setReplyChannel(MessageChannel replyChannel)
public void setErrorChannelName(String errorChannelName)
public void setErrorChannel(MessageChannel errorChannel)
public String getShortLogMessage(Object payload)
payload
- the payload that corresponds to the headers.public String getDetailedLogMessage(@Nullable Object payload)
payload
- the payload that corresponds to the headers.protected String getDetailedPayloadLogMessage(@Nullable Object payload)
protected boolean isReadableContentType()
@Nullable public static MessageHeaderAccessor getAccessor(Message<?> message)
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.
message
- the message to get an accessor fornull
if none@Nullable public static <T extends MessageHeaderAccessor> T getAccessor(Message<?> message, @Nullable Class<T> requiredType)
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.
message
- the message to get an accessor forrequiredType
- the required accessor type (or null
for any)null
if none@Nullable public static <T extends MessageHeaderAccessor> T getAccessor(MessageHeaders messageHeaders, @Nullable Class<T> requiredType)
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.
messageHeaders
- the message headers to get an accessor forrequiredType
- the required accessor type (or null
for any)null
if nonepublic static MessageHeaderAccessor getMutableAccessor(Message<?> message)
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.
null
)