Spring集成MessageTransformationException无法转换消息

时间:2013-11-16 17:28:21

标签: amqp spring-integration

我正在尝试使用spring integration 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>
...

DEBUG:

  

DEBUG:http-bio-8080-exec-3   org.springframework.integration.channel.DirectChannel - postSend   (发送= true)在频道'amqpOut'上,消息:   [有效载荷= 826bcbfb-21FA-424D-AECD-0bab3d1a690b] [接头= {时间戳= 1384617973920,   id = e98cd0c1-bd8c-4786-be31-1e77b0200934,content-type = text / x-json}]

     

DEBUG:http-bio-8080-exec-3   org.springframework.integration.channel.DirectChannel - postSend   (发送= true)在频道'jsonOrders'上,消息:   [有效载荷= { “ID”:1, “批准”:假, “保留”:假, “客户ID”: “”, “量”:1, “的productId”: “微件”}] [接头= {时间戳= 1384617973852,   id = 826bcbfb-21fa-424d-aecd-0bab3d1a690b,content-type = text / x-json}]

     

DEBUG: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}]

     

DEBUG:   SimpleAsyncTaskExecutor-1   org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper -   headerName = [content-type]将被映射,匹配的pattern = content-type

     

DEBUG:SimpleAsyncTaskExecutor-1   org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper -   headerName = [amqp_receivedRoutingKey]将被映射,匹配   pattern = amqp_receivedRoutingKey

     

DEBUG:SimpleAsyncTaskExecutor-1   org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper -   headerName = [amqp_deliveryMode]将被映射,匹配   pattern = amqp_deliveryMode

     

DEBUG:SimpleAsyncTaskExecutor-1   org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper -   headerName = [amqp_redelivered]将被映射,匹配   pattern = amqp_redelivered

     

DEBUG:SimpleAsyncTaskExecutor-1   org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper -   headerName = [amqp_deliveryTag]将被映射,匹配   pattern = amqp_deliveryTag

     

DEBUG:SimpleAsyncTaskExecutor-1   org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper -   headerName = [content-type]将被映射,匹配的pattern = content-type

     

DEBUG:SimpleAsyncTaskExecutor-1   org.springframework.integration.channel.DirectChannel - preSend on   channel'orderChannel',消息:   [有效载荷= ??? SR?java.util.UUID中????毫升/?J〜leastSigBitsJ?mostSigBitsxp ??? = I·K ??!?] [接头= {时间戳= 1384617974260,   id = 81a2fb77-0f1e-4be7-9148-84da86a30ed8,content-type = text / x-json,   amqp_receivedRoutingKey = orders,amqp_deliveryMode = PERSISTENT,   amqp_redelivered = false,amqp_deliveryTag = 1}]

     

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

1 个答案:

答案 0 :(得分:3)

嗯,你的问题在这里:

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

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

发生了什么事?

您的UUID将被SimpleMessageConverter转换为序列化字节,此转换器将设置 contentType application/x-java-serialized-object MessageProperties AmqpHeaderMapper。 但在此之后被称为contentType,他会使用text/x-json中的MessageHeaders值更改SimpleMessageConverter。 这对制片人来说很好。

但消费者无法正确转换Body,因为默认情况下此处也可以contentType.startsWith("text")。 它会检查UUID。 只需从序列化<object-to-json-transformer>的字节创建简单的String。

希望很清楚

<强>更新

不幸的是,content-type无论如何都设置了application/json标头,默认为content-type=""

为防止出现这种情况,您应该像{{1}}一样进行配置。