【问题标题】:Spring integration MessageTransformationException failed to transform messageSpring集成MessageTransformationException未能转换消息
【发布时间】:2013-11-16 17:28:21
【问题描述】:

我正在尝试使用 spring 集成 v2.2.6.RELEASE 运行这个 (https://github.com/cloudfoundry-samples/wgrus/tree/master/spring-integration) wgrus 示例应用程序并不断收到 MessageTransformationException。该应用程序分为 3 个组件 - 一个商店 UI、一个库存服务和一个运输服务(此服务在此无关紧要),并使用 AMQP 协议向 RabbitMQ 发送消息。简而言之,您在 UI 中输入订单详细信息,然后以消息的形式将其发送到订单渠道。在幕后,应用程序执行声明检查,将消息存储在 Mongo 中(我可以看到它已被存储)并返回一条新消息,其有效负载是存储消息的 id - 到目前为止一切顺利,消息已存储我可以看到 amqpOut 通道返回存储消息的 ID,即 826bcbfb-21fa-424d-aecd-0bab3d1a690b - 这可以在我的问题底部显示的调试中看到。接下来,消息通过出站 AMQP 通道发送到 RabbitMQ,并且应该由库存服务提取,此时抛出异常。我可以看到,在调试打印 Payload=???sr?java.util.UUID????m?/

时,存储消息的 id 有时会发生某些事情

有没有人遇到过这个问题并知道如何解决?

商店 UI 使用的配置:

<int:object-to-json-transformer input-channel="orderChannel" output-channel="jsonOrders" content-type="text/x-json"/>

<int:claim-check-in input-channel="jsonOrders" output-channel="amqpOut" message-store="messageStore"/>

<amqp:outbound-channel-adapter id="amqpOut" amqp-template="rabbitTemplate" routing-key="orders"/>
...

库存服务使用的配置:

<int:claim-check-out message-store="messageStore" input-channel="orderChannel" output-channel="inventoryChannel" remove-message="true" />

<amqp:inbound-channel-adapter channel="orderChannel"
  connection-factory="rabbitConnectionFactory"
  queue-names="orders"
  error-channel="errorLogger" />

<int:logging-channel-adapter id="errorLogger" log-full-message="true" level="INFO"/>

<int:chain input-channel="inventoryChannel" output-channel="amqpOut">
  <int:json-to-object-transformer type="org.wgrus.Order"/>
  <int:enricher request-channel="creditCheck">
    <int:property name="approved" expression="payload.startsWith('OK')"/>
  </int:enricher>
  <int:enricher request-channel="inventoryRouter">
    <int:property name="reserved" expression="payload"/>
  </int:enricher>
  <int:object-to-json-transformer content-type="text/x-json" />
  <int:claim-check-in/>
</int:chain>
...

调试:

调试:http-bio-8080-exec-3 org.springframework.integration.channel.DirectChannel - postSend (sent=true) 在频道“amqpOut”上,消息: [有效负载=826bcbfb-21fa-424d-aecd-0bab3d1a690b][标题={时间戳=1384617973920, id=e98cd0c1-bd8c-4786-be31-1e77b0200934, content-type=text/x-json}]

调试:http-bio-8080-exec-3 org.springframework.integration.channel.DirectChannel - postSend (sent=true) 在频道 'jsonOrders' 上,消息: [Payload={"id":1,"approved":false,"reserved":false,"customerId":"","quantity":1,"productId":"widget"}][Headers={timestamp= 1384617973852, id=826bcbfb-21fa-424d-aecd-0bab3d1a690b, content-type=text/x-json}]

调试:http-bio-8080-exec-3 org.springframework.integration.channel.DirectChannel - postSend (sent=true) 在频道 'orderChannel' 上,消息:[Payload=Order #1: 1 ][Headers={timestamp=1384617973824, id=1b700a4b-35e1-4d16-8ca0-7cd20ccfb85e}]

调试: SimpleAsyncTaskExecutor-1 org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper - headerName=[content-type] 将被映射,匹配模式=content-type

调试:SimpleAsyncTaskExecutor-1 org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper - headerName=[amqp_receivedRoutingKey] 将被映射,匹配 模式=amqp_receivedRoutingKey

调试:SimpleAsyncTaskExecutor-1 org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper - headerName=[amqp_deliveryMode] 将被映射,匹配 模式=amqp_deliveryMode

调试:SimpleAsyncTaskExecutor-1 org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper - headerName=[amqp_redelivered] 将被映射,匹配 模式=amqp_redelivered

调试:SimpleAsyncTaskExecutor-1 org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper - headerName=[amqp_deliveryTag] 将被映射,匹配 模式=amqp_deliveryTag

调试:SimpleAsyncTaskExecutor-1 org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper - headerName=[content-type] 将被映射,匹配模式=content-type

调试:SimpleAsyncTaskExecutor-1 org.springframework.integration.channel.DirectChannel - preSend on 频道“orderChannel”,消息: [有效负载=???sr?java.util.UUID????m?/?J?leastSigBitsJ?mostSigBitsxp???=i?k??!?][标头={timestamp=1384617974260, id=81a2fb77-0f1e-4be7-9148-84da86a30ed8,内容类型=文本/x-json, amqp_receivedRoutingKey=订单,amqp_deliveryMode=PERSISTENT, amqp_redelivered=false, amqp_deliveryTag=1}]

调试:SimpleAsyncTaskExecutor-1 org.springframework.integration.transformer.MessageTransformingHandler - org.springframework.integration.transformer.MessageTransformingHandler#1 收到消息:[Payload=???sr?java.util.UUID????m?/?J?

【问题讨论】:

    标签: amqp spring-integration


    【解决方案1】:

    好吧,你的问题就在这里:

    <int:object-to-json-transformer input-channel="orderChannel" output-channel="jsonOrders" content-type="text/x-json"/>
    

    你能解释一下设置content-type的原因是什么,如果你之后使用&lt;claim-check-in&gt;,谁只返回UUID - 存储消息的id?

    发生了什么?

    您的UUIDSimpleMessageConverter 转换为序列化字节,并且此转换器设置 contentType 作为application/x-java-serialized-objectMessageProperties。 但在那之后被称为AmqpHeaderMapper,他用你的值text/x-jsonMessageHeaders更改contentType。 这对 Producer 来说很好。

    但 Consumer 无法正确转换 Body,因为这里默认情况下也可以使用 SimpleMessageConverter。 它会检查contentType.startsWith("text")。 只需从序列化的UUID 字节创建简单的字符串。

    希望清楚

    更新

    不幸的是,&lt;object-to-json-transformer&gt;content-type 标头默认设置为 application/json

    为了防止它,你应该像这样配置content-type=""

    【讨论】:

    • 感谢您的快速回复。针对您的问题:您能否解释设置内容类型的原因是什么,如果您之后使用 ,谁只返回 UUID - 存储消息的 id?在这里阅读了第 6 节的“重要”部分http://docs.spring.io/spring-integration/docs/2.2.6.RELEASE/reference/html/messaging-transformation-chapter.html#transformer 我的印象是需要在我的情况下设置内容类型。
    • 我的印象是,在使用 spring 集成 2.2 版时必须设置内容类型才能解决 MessageTransformationException,我在设置内容类型属性之前也得到了该异常。我现在再次删除了内容类型以确认我仍然得到相同的异常(我仍然得到它)。如果你能告诉我我做错了什么,我将不胜感激。
    • 我在答案中又添加了一个选项
    猜你喜欢
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 2018-08-25
    相关资源
    最近更新 更多