|
如需使用最新稳定版本,请使用 Spring Integration 7.0.4! |
AMQP 消息头
概述
Spring Integration AMQP 适配器会自动映射所有 AMQP 属性和标头。
(这是与 4.3 版本的变化——此前,仅映射标准标头)。
默认情况下,这些属性通过
DefaultAmqpHeaderMapper在 Spring Integration MessageHeaders 之间进行复制。
您可以传入自己实现的 AMQP 特定头部映射器,因为适配器具有支持此操作的相关属性。
AMQP MessageProperties 中的任何用户自定义标头都会被复制到一个 AMQP 消息中,除非被 DefaultAmqpHeaderMapper 的 requestHeaderNames 或 replyHeaderNames 属性显式否定。
默认情况下,对于出站映射器,不会映射任何 x-* 标头。
有关原因,请参阅本节后面出现的 警告。
要覆盖默认设置并恢复到 4.3 版本之前的行为,请在属性中使用 STANDARD_REQUEST_HEADERS 和
STANDARD_REPLY_HEADERS。
在映射用户自定义标头时,值也可以包含简单的通配符模式(例如 thing* 或 *thing)进行匹配。
* 匹配所有标头。 |
从版本 4.1 开始,AbstractHeaderMapper(一个 DefaultAmqpHeaderMapper 超类)允许为 requestHeaderNames 和 replyHeaderNames 属性配置 NON_STANDARD_HEADERS Tokens(除了现有的 STANDARD_REQUEST_HEADERS 和 STANDARD_REPLY_HEADERS),以映射所有用户定义的标头。
org.springframework.amqp.support.AmqpHeaders 类标识 DefaultAmqpHeaderMapper 使用的默认标头:
-
amqp_appId -
amqp_clusterId -
amqp_contentEncoding -
amqp_contentLength -
content-type(see ThecontentType标头) -
amqp_correlationId -
amqp_delay -
amqp_deliveryMode -
amqp_deliveryTag -
amqp_expiration -
amqp_messageCount -
amqp_messageId -
amqp_receivedDelay -
amqp_receivedDeliveryMode -
amqp_receivedExchange -
amqp_receivedRoutingKey -
amqp_redelivered -
amqp_replyTo -
amqp_timestamp -
amqp_type -
amqp_userId -
amqp_publishConfirm -
amqp_publishConfirmNackCause -
amqp_returnReplyCode -
amqp_returnReplyText -
amqp_returnExchange -
amqp_returnRoutingKey -
amqp_channel -
amqp_consumerTag -
amqp_consumerQueue
正如本节前面所述,使用 * 的头部映射模式是复制所有头部的常用方法。然而,这可能会产生一些意想不到的副作用,因为某些 RabbitMQ 专有属性/标头也会被复制。例如,当您使用 联合 时,接收到的消息可能包含一个名为 x-received-from 的属性,该属性包含发送消息的节点。如果您在入站网关的请求和回复头映射中使用通配符字符 *,该头将被复制,这可能会引起一些联合问题。此回复消息可能会被回传至发送代理,这可能导致代理认为消息正在循环,从而静默丢弃该消息。如果您希望使用通配符头部映射的便利性,您可能需要在下游流程中过滤掉某些头部。例如,为了避免将 x-received-from 响应头复制回回复中,您可以在向 AMQP 入站网关发送回复之前使用 <int:header-filter … header-names="x-received-from">。或者,您可以显式列出您实际希望映射的属性,而不是使用通配符。出于这些原因,对于入站消息,映射器(默认情况下)不会映射任何 x-* 标头。它也不会将 deliveryMode 映射到 amqp_deliveryMode 标头,以避免将该标头从入站消息传播到出站消息。相反,此标头被映射到 amqp_receivedDeliveryMode,该值在输出中未进行映射。
|
从版本 4.3 开始,可以在头部映射的模式前加上 ! 来否定该模式。
被否定的模式具有优先级,因此像 STANDARD_REQUEST_HEADERS,thing1,ba*,!thing2,!thing3,qux,!thing1 这样的列表不会映射 thing1(也不会映射 thing2 或 thing3)。
标准头部以及 bad 和 qux 会被映射。
这种否定技术非常有用,例如,当 JSON 反序列化逻辑在下游接收器中以不同方式执行时,可以防止为传入消息映射 JSON 类型的头部。
为此,应在入站通道适配器/网关的头部映射器中配置一个 !json_* 模式。
如果您有一个以 ! 开头且确实希望映射的用户自定义标头,则需要使用 \ 对其进行转义,如下所示:STANDARD_REQUEST_HEADERS,\!myBangHeader。
现在已映射名为 !myBangHeader 的标头。 |
从版本 5.1 开始,如果出站消息中不存在相应的 amqp_messageId 或 amqp_timestamp 标头,DefaultAmqpHeaderMapper 将回退到分别将 MessageHeaders.ID 和 MessageHeaders.TIMESTAMP 映射为 MessageProperties.messageId 和 MessageProperties.timestamp。
入站属性将像以前一样映射到 amqp_* 标头。
当消息消费者使用有状态重试时,填充 messageId 属性非常有用。 |
这contentTypeheader
与其他头部不同,AmqpHeaders.CONTENT_TYPE前没有添加amqp_;这使得contentType头部能够在不同技术之间透明传递。
例如,发送到RabbitMQ队列的入站HTTP消息。
The contentType 页头映射到 Spring AMQP 的 MessageProperties.contentType 属性,随后该属性再映射到 RabbitMQ 的 content_type 属性。
在 5.1 版本之前,此标头也被映射为 MessageProperties.headers 映射中的一个条目;这是不正确的,而且由于底层的 Spring AMQP 消息转换器可能已更改内容类型,该值也可能是错误的。
此类更改会反映在第一类 content_type 属性中,但不会反映在 RabbitMQ 标头映射中。
入站映射忽略了标头映射的值。
contentType 不再映射到标头映射中的条目。