SpringCloud 机械学

2023-11-27 12:01 更新

为了更好地理解内容类型协商的机制和必要性,我们以下面的消息处理程序为例,看一个非常简单的用例:

@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public String handle(Person person) {..}

 为简单起见,我们假设这是应用程序中唯一的处理程序(我们假设没有内部管道)。

前面示例中所示的处理程序期望将Person对象作为参数,并产生String类型作为输出。为了使框架成功将传入的Message作为参数传递给此处理程序,它必须以某种方式将Message类型的有效负载从有线格式转换为Person类型。换句话说,框架必须找到并应用适当的MessageConverter为此,该框架需要用户提供一些指导。处理程序方法本身的签名(Person类型)已经提供了这些指令之一。因此,从理论上讲,这应该是(并且在某些情况下是足够的)。但是,对于大多数用例而言,为了选择适当的MessageConverter,框架需要额外的信息。缺少的部分是contentType

Spring Cloud Stream提供了三种机制来定义contentType(按优先顺序):

    1.标题contentType可以通过消息本身进行通信。通过提供contentType标头,您可以声明用于查找和应用适当的MessageConverter的内容类型。
    2.绑定:可以通过设置spring.cloud.stream.bindings.input.content-type属性为每个目标绑定设置contentType

 属性名称中的input段与目的地的实际名称相对应(在本例中为“输入”)。通过这种方法,您可以在每个绑定的基础上声明用于查找和应用适当的MessageConverter的内容类型。

    3.默认值:如果Message标头或绑定中不存在contentType,则使用默认的application/json内容类型来查找和应用适当的MessageConverter

如前所述,前面的列表还演示了平局时的优先顺序。例如,标头提供的内容类型优先于任何其他内容类型。对于按绑定设置的内容类型也是如此,这实际上使您可以覆盖默认内容类型。但是,它也提供了明智的默认值(由社区反馈确定)。

application/json设置为默认值的另一个原因是由分布式微服务体系结构驱动的互操作性要求,在该体系结构中,生产者和使用者不仅可以在不同的JVM中运行,而且还可以在不同的非JVM平台上运行。

当非无效处理程序方法返回时,如果返回值已经是Message,则该Message成为有效负载。但是,当返回值不是Message时,将使用返回值作为有效负载构造新的Message,同时从输入Message继承标头减去由SpringIntegrationProperties.messageHandlerNotPropagatedHeaders定义或过滤的标头。默认情况下,仅设置一个标头:contentType这意味着新的Message没有设置contentType头,从而确保contentType可以演进。您始终可以选择不从处理程序方法返回Message的位置,在该方法中可以注入所需的任何标头。

如果存在内部管道,则通过相同的转换过程将Message发送到下一个处理程序。但是,如果没有内部管道或您已经到达内部管道的末尾,则Message将发送回输出目的地。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号