首页 > 技术文章 > Camel 中基于内容的路由

d1012181765 2021-09-26 16:01 原文

Camel's choice() 和 when() - 示例

了解如何使用基于内容的路由器、choice() 和 when() 以及谓词在 Apache Camel 中有条件地路由消息。

Apache Camel 包含一个强大的特性,称为基于内容的路由器。这允许您根据消息的内容以不同的方式处理消息。在本文中,我将向您展示如何使用基于内容的路由器,并向您展示可用于编写条件的不同选项。一路上还有一些示例代码。

基础知识

当您需要根据某些事实有条件地路由消息时,您可以使用choiceandwhen构造。

这些与if/elseJava 中的构造非常相似。但是,在 Camel 中,等效的词是whenand otherwise

Java 中典型的 if/else 块可能如下所示:

if (condition) {
    // ... do something ...
} else if (condition) {
    // ... do something else ...
} else {
    // otherwise do this
}

但是在 Camel 的 Java DSL 中,它看起来像这样:

from(anEndpoint)
    .choice()
        .when(someCondition).to(firstEndpoint)
        .when(anotherCondition).to(secondEndpoint)
    .otherwise()
        .to(thirdEndpoint)
    .end();

注意如何:

  • 我们以choice()-开始块- 这告诉 Camel 以下行将包含一些要评估的条件。

  • 每个when()方法都指示要评估的新条件,类似于if核心 Java

  • 该方法otherwise()定义了当前面的when()条件都不相等时要执行的操作true

  • 块以 .end()结束。

如何在 Camel 中构建 when 条件

在编写when()条件时,您有许多不同的选择。在 Camel 中,这称为构建谓词。您可以使用多种语言来构建谓词,但最常见的是:

  • 简单语言,Camel 自己的语言,用于构建简单的字符串比较

  • Header,用于根据 Exchange 上 Header 的值构建条件

  • Bean 语言,当您想使用 Java 方法调用的结果时

  • XPath 或 JSONPath,当您要在 XML 文档或 JSON 文档中进行搜索时

(有关支持的语言的完整列表,请参阅Camel 文档中的语言条目。)

示例 Camel 谓词

以下是 Camel 中谓词的一些示例,以及它们的含义:

示例谓词它能做什么
.when(body().contains("Hello, world!")) 当消息的正文包含字符串时 "Hello, world!"
.when().simple("${body} == 'Disco'") 使用Simple 语言测试消息正文何时准确"Disco"
.when(header("country").isEqualTo("GB")) 当具有名称的 Headercountry等于"GB"
.when(header("CamelFileName") .isEqualTo("disco.txt")) 使用File 组件,检查接收到的文件的名称是否为disco.txt
.when(header("CamelFileName").endsWith(".xml")) 使用 File 组件,使用PredicateBuilder.endsWith()检查收到的文件名是否以.xml
.when(header("country").regex("US | FR | DE")) 使用 Camel 的正则表达式方法,检查具有名称的 Header 的值countryUS,FR或 之一DE
.when(xpath("/customer/@status = 'gold'")) 使用 Camel 的 XPath 支持,检查元素status上的属性值customer是否等于gold

向您的 when() 条件添加操作

每个when()条件基本上都建立了一个迷你管道。您可以按照when()with to(), 告诉 Camel 根据特定条件将消息路由到端点。

例如,下面的代码片段会将消息路由到一个 ActiveMQ 队列,hello如果它包含文本,则调用它Hello, world!

.when(body().contains("Hello, world!")).to("activemq:queue:hello")

您还可以在您的迷你管道中堆叠多个 Camel DSL 函数,就像您if在 Java 中在一个块中编写多个语句一样。

这是在when()条件中使用多个语句的示例。它使用setBody()方法更改消息正文,然后使用 File 组件将其写入磁盘上的文件夹:

.when(body().contains("Hello, world!"))
      .setBody(simple("Goodbye, world!"))
      .to("file:customers/out/goodbye")

使用 'otherwise' 来指定你的 'else' 块

定义所有when()条件和操作后,您可能希望定义在您的消息与之前的条件不匹配时应采取的操作。

就像else声明一样,Camelotherwise允许您执行此操作。例如,您可能希望记录消息,或将其移至死信队列。

.otherwise().to("activemq:queue:unprocessed")

把这一切放在一起

现在让我们把我们在本文中学到的一切都放到一个例子中,展示您通常如何使用choice()when()在您的 Camel 路线中。

from("file:src/data?noop=true")
    .to("log:ordersReceived")
    .choice()
        // If the customer has a type="business"
        .when(xpath("/order/customer/@type = 'business'"))
            .log("Business order received")
            .to("file:out/business")
​
        // If the customer has a type="personal"
        .when(xpath("/order/customer/@type = 'personal'"))
            .log("Personal order received")
            .to("file:out/personal")
​
        .otherwise()
            .log("Other order received")
            .to("file:out/others")
    .end();

在上面的例子中:

  • 该路由以使用 File 组件从磁盘上的某个位置读取文件的指令开始 ( src/data)

  • 使用记录器名称将有关接收到的文件的信息写入日志ordersReceived

  • XPath 测试应用于传入文件以检查它是否是商业客户订单。如果是,则将文件移动到out/business文件夹中。

  • 第二个测试检查订单是否来自个人客户。如果是,则将文件移动到out/personal文件夹中。

  • 最后,如果以上两个条件都不为true,则文件将移动到out/others文件夹中。

这是否有助于您了解如何在 Camel 路线中使用when,choiceotherwise?请在下面的评论中发表您的反馈!

 

推荐阅读