Spring Integration消息<payload> vs Payload作为输出参数

时间:2015-07-16 09:25:58

标签: spring-integration

我有一个spring集成流,其中包含一个带有import org.json4s._ import org.json4s.DefaultFormats import org.json4s.native.JsonMethods._ object Testing { implicit val formats = DefaultFormats.withBigDecimal def test = { val json = parse("""{"some_field":"a value"}""").camelizeKeys json.extract[ThingDTO] } } case class ThingDTO(someField:String) 的jdbc出站网关 最初我的网关方法就像

select query SELECT * FROM  Users WHERE userId=:payload

我有行映射器,它将数据从sql结果映射到UserBO对象。 在上面的例子中,即使sql结果集中有1行或更多行,我也总是得到一个用户列表。

我已将网关方法更改为

public List<UserBO> findUser(String userId);

因为我需要来自邮件的标头值。 现在问题是当sql结果集中有2行或更多行时,返回消息中的有效负载是用户对象列表。但是如果sql结果集中只有一行,则有效负载是UserBO对象;不是userBO对象的列表。

所以我需要在处理响应消息之前检查有效负载的实例。 这是Spring集成的预期行为吗?

1 个答案:

答案 0 :(得分:1)

啊!我知道了。问题出在ConversionService

Spring Integration中的所有组件都接受Message<?>并独立于参数提取返回Message<?>

这是第一个事实。

第二个:JdbcOutboundGateway有一个代码:

if (list.size() == 1) {
    payload = list.get(0);
}
return this.getMessageBuilderFactory().withPayload(payload).copyHeaders(requestMessage.getHeaders()).build();

正如您之前所说,它会返回Message<?>,但请注意payload它有哪些内容。

链中的下一个事实。

您的网关方法有签名:

public Message<List<UserBO>> findUser(String userId);

所以,返回Message<?>!由于我们已收到JdbcOutboundGateway回复中的消息,因此无需关注payload 转换。瞧!您希望得到Message<List<UserBO>>,但它只是Message<UserBO>,因为JdbcOutboundGateway逻辑。

由于泛型是一个编译时功能,我们可以简单地将最后一个强制转换为第一个,但是当我们尝试从中提取ClassCastException时,我们得到payload

第一种情况很有效,因为我们从回复邮件中提取您的单个UserBO payload并将其发送到ConversionService以转换为List<UserBO>作为您的第一个变体需要。

在这种情况下,它可以简单地为我们实例化Collection并在那里填充我们的单个对象。

Message<T>案件无动于衷。因为我们无法从那里提取泛型类型。或者甚至更好,我们不想这样做。因为与Message对象的这种通信正好允许我们绕过ConversionService并获得更好的性能和吞吐量。

希望我很清楚。