AMQP Message Headers

Overview

Spring Integration AMQP 适配器自动映射所有 AMQP 属性和标头。(这是 4.3 版的一个更改 - 以前仅映射标准标头)。默认情况下,这些属性使用 DefaultAmqpHeaderMapper 复制到 Spring Integration MessageHeaders 和从 Spring Integration MessageHeaders 复制到 Spring Integration MessageHeaders

可以传入 AMQP 特定标头映射器的自定义实现,因为适配器具有支持此操作的属性。

AMQP MessageProperties 中的所有用户定义头都会被复制到 AMQP 消息中或从 AMQP 消息中复制,除非 DefaultAmqpHeaderMapperrequestHeaderNamesreplyHeaderNames 属性明确地否定了它们。默认情况下,对于出站映射器,没有一个 x-* 头被映射。有关原因,请参阅稍后在本章节中出现的 caution

若要覆盖默认设置并恢复到 4.3 之前的行为,请在属性中使用 STANDARD_REQUEST_HEADERSSTANDARD_REPLY_HEADERS

映射用户定义的头时,值还可以包含简单的通配符模式(例如,thing*thing) to be matched. The 匹配所有标头)。

从 4.1 版开始,AbstractHeaderMapperDefaultAmqpHeaderMapper 超类)允许为 requestHeaderNamesreplyHeaderNames 属性(除现有的 STANDARD_REQUEST_HEADERSSTANDARD_REPLY_HEADERS 外)配置 `NON_STANDARD_HEADERS`令牌,以映射所有用户定义的标头。

org.springframework.amqp.support.AmqpHeaders 类标识由 DefaultAmqpHeaderMapper 使用的默认标头:

  • amqp_appId

  • amqp_clusterId

  • amqp_contentEncoding

  • amqp_contentLength

  • content-type(参见 The contentType Header

  • 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

正如本节前面提到的,对入站网关的请求和答复标头映射使用 is a common way to copy all headers. However, this can have some unexpected side effects, because certain RabbitMQ proprietary properties/headers are also copied. For example, when you use federation, the received message may have a property named x-received-from, which contains the node that sent the message. If you use the wildcard character 的标头映射模式,此标头会被复制,这可能会导致联合的一些问题。此答复报文可能会联合回发送代理程序,而代理程序可能认为报文正在循环并且因此静默地丢弃它。如果您希望使用通配符标头映射的便利性,您可能需要在下游流中过滤掉一些标头。例如,要避免将 x-received-from 标头复制回答复,您可以在将答复发送到 AMQP 入站网关之前使用 <int:header-filter …​ header-names="x-received-from">。或者,您可以显式列出您实际想要映射的那些属性,而不是使用通配符。由于这些原因,对于入站报文,映射器(默认情况下)不会映射任何 x-* 标头。它也不会将 deliveryMode 映射到 amqp_deliveryMode 标头,以避免该标头从入站报文传播到出站报文。相反,此标头映射到 amqp_receivedDeliveryMode,而 amqp_receivedDeliveryMode 在输出时不会被映射。

从 4.3 版开始,可以在标头映射中使用 ! 否定模式,方法是在模式前加 !。否定模式具有优先级,所以诸如 STANDARD_REQUEST_HEADERS,thing1,ba*,!thing2,!thing3,qux,!thing1 的列表不会映射 thing1(也不会映射 thing2thing3)。将映射标准标头加上 badqux。否定技术可能很有用,例如在接收器在不同下游采用 JSON 反序列化逻辑时,不为传入消息映射 JSON 类型标头。为此目的,应为入站通道适配器/网关的标头映射器配置 !json_* 模式。

如果你有一个以 ! 开头的用户自定义标头,并且希望映射它,你需要使用 \ 对其进行转义,如下所示:STANDARD_REQUEST_HEADERS,\!myBangHeader。名为 !myBangHeader 的标头现在已映射。

从版本 5.1 开始,如果出站消息中不存在对应的 amqp_messageIdamqp_timestamp 标头,DefaultAmqpHeaderMapper 将回退为将 MessageHeaders.IDMessageHeaders.TIMESTAMP 分别映射到 MessageProperties.messageIdMessageProperties.timestamp。入站属性将像以前一样映射到 amqp_* 标头。当消息使用者使用有状态重试时,填充 messageId 属性很有用。

The contentType Header

与其他标头不同,AmqpHeaders.CONTENT_TYPE 不带 amqp_ 前缀;这允许跨不同技术透明地传递 contentType 标头。例如,发送到 RabbitMQ 队列的入站 HTTP 消息。

contentType 标头映射到 Spring AMQP 的 MessageProperties.contentType 属性,然后映射到 RabbitMQ 的 content_type 属性。

在版本 5.1 之前,此标头也映射为 MessageProperties.headers 映射中的一个条目;这是不正确的,并且,此外,值可能是错误的,因为基础 Spring AMQP 消息转换器可能已更改了内容类型。此类更改将反映在一流的 content_type 属性中,但不会反映在 RabbitMQ 标头映射中。入站映射忽略标头映射值。contentType 不再映射为标头映射中的一个条目。