出站訊息轉換

Spring AMQP 1.4 引入了 ContentTypeDelegatingMessageConverter,它根據入站內容型別訊息屬性選擇實際的轉換器。入站端點可以使用此功能。

從 Spring Integration 4.3 版本開始,您也可以在出站端點上使用 ContentTypeDelegatingMessageConverter,透過 contentType 頭來指定使用哪個轉換器。

以下示例配置了一個 ContentTypeDelegatingMessageConverter,預設轉換器為 SimpleMessageConverter(用於處理 Java 序列化和純文字),此外還配置了一個 JSON 轉換器

<amqp:outbound-channel-adapter id="withContentTypeConverter" channel="ctRequestChannel"
                               exchange-name="someExchange"
                               routing-key="someKey"
                               amqp-template="amqpTemplateContentTypeConverter" />

<int:channel id="ctRequestChannel"/>

<rabbit:template id="amqpTemplateContentTypeConverter"
        connection-factory="connectionFactory" message-converter="ctConverter" />

<bean id="ctConverter"
        class="o.s.amqp.support.converter.ContentTypeDelegatingMessageConverter">
    <property name="delegates">
        <map>
            <entry key="application/json">
                <bean class="o.s.amqp.support.converter.Jackson2JsonMessageConverter" />
            </entry>
        </map>
    </property>
</bean>

ctRequestChannel 傳送一條 contentType 頭設定為 application/json 的訊息將導致選中 JSON 轉換器。

這適用於出站通道介面卡和出站閘道器。

從 5.0 版本開始,新增到出站訊息的 MessageProperties 中的頭(預設情況下)不會被對映的頭覆蓋。以前,只有在使用 ContentTypeDelegatingMessageConverter 作為訊息轉換器時才如此(在這種情況下,先對映頭以便選擇合適的轉換器)。對於其他轉換器,例如 SimpleMessageConverter,對映的頭會覆蓋由轉換器新增的任何頭。當出站訊息包含一些殘留的 contentType 頭(可能來自入站通道介面卡)並且正確的出站 contentType 被錯誤覆蓋時,這會導致問題。解決方法是使用頭過濾器在將訊息傳送到出站端點之前移除該頭。

但是,在某些情況下需要先前的行為——例如,當 String 載荷包含 JSON 時,SimpleMessageConverter 並不知道內容,並將 contentType 訊息屬性設定為 text/plain,但您的應用程式希望透過設定傳送到出站端點的訊息的 contentType 頭來將其覆蓋為 application/jsonObjectToJsonTransformer 預設就是這樣做的。

現在,出站通道介面卡和閘道器(以及基於 AMQP 的通道)上有一個名為 headersMappedLast 的屬性。將其設定為 true 可以恢復覆蓋由轉換器新增的屬性的行為。

從 5.1.9 版本開始,當產生回覆並希望覆蓋由轉換器填充的頭時,為 AmqpInboundGateway 提供了一個類似的 replyHeadersMappedLast 屬性。有關更多資訊,請參閱其 JavaDocs。