我有一个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集成的预期行为吗?
答案 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
并获得更好的性能和吞吐量。
希望我很清楚。