知識庫 / Spring RSS 訂閱

Apache Camel 條件路由

Spring
HongKong
5
11:54 AM · Dec 06 ,2025

1. 概述

Apache Camel 是一個強大的開源集成框架,實現了多種已知的企業集成模式。

通常在使用 Camel 進行消息路由時,我們需要根據消息內容以不同的方式處理消息。為此,Camel 提供了一個強大的功能,稱為 基於內容路由器,來自 企業集成模式 集合。

在本教程中,我們將探討多種基於條件的消息路由方法。

2. 依賴項為了開始,我們只需要將 camel-spring-boot-starter 添加到我們的 pom.xml 中:

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
     <artifactId>camel-spring-boot-starter</artifactId>
     <version>4.3.0</version>
</dependency>

然後,我們需要將 <em><a href="https://mvnrepository.com/artifact/org.apache.camel/camel-test-spring-junit5">camel-test-spring-junit5</a></em>&nbsp; 依賴添加到我們的 <em>pom.xml</em>&nbsp; 中:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-test-spring-junit5</artifactId>
    <version>4.3.0</version>
</dependency>

正如其名稱所示,這個依賴項專門用於我們的單元測試。

3. 定義一個簡單的 Camel Spring Boot 應用

在整個教程中,我們示例的重點將是簡單的 Camel Spring Boot 應用。

讓我們首先定義應用程序的入口點:

@SpringBootApplication
public class ConditionalRoutingSpringApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConditionalRoutingSpringApplication.class, args);
    }
}

如我們所見,這是一個標準的 Spring Boot 應用。

4. 條件路由

為了快速回顧,Apache Camel 中的 路由 是一個基本構建塊,通常由 Camel 執行的順序步驟組成,用於消費和處理消息。

例如,路由通常會接收一條消息,使用例如從磁盤上的文件或消息隊列的消費者。然後,Camel 執行路由中的其餘步驟,無論是否處理消息,或者將其發送到其他端點。

毫無疑問,我們想要一種基於某些事實來條件路由消息的方式。為此,Camel 提供了 choicewhen 構造。我們可以將其視為 Java 中 if-else 語句的等效項。

考慮到這一點,讓我們創建一個帶有條件邏輯的第一個路由。

5. 創建路由

在示例中,我們將定義一個基本的路由,並根據消息主體的內容包含一些條件邏輯:

@Component
public class ConditionalBodyRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        
        from("direct:start-conditional")
          .routeId("conditional-body-route")
          .choice()
            .when(body().contains("Baeldung"))
              .setBody(simple("Goodbye, Baeldung!"))
              .to("mock:result-body")
            .otherwise()
              .to("mock:result-body")
          .end();
    }
}

如我們所見,在我們的簡單示例中,我們配置路由以從一個 直接端點 start-conditional 中消費消息。

現在,讓我們逐步瞭解路由的關鍵部分:

  • 首先,我們使用 choice() 方法開始路由 – 這告訴 Camel 後面的行將包含一些條件進行評估
  • 接下來,when() 方法指示一個新的條件進行評估 – 在本例中,我們簡單地檢查消息主體是否包含字符串 Baeldung。我們可以添加任意數量的 when 條件
  • 為了總結路由,我們使用 otherwise() 方法定義在沒有滿足任何先前 when 條件的情況下該執行的操作。
  • 最後,路由使用 end() 方法終止,該方法關閉 choice 塊。

總而言之,當運行我們的路由時,如果消息主體包含字符串 Baeldung,我們將消息主體設置為 Goodbye, Baeldung! 並將結果發送到名為 result-body模擬端點

或者,我們只需將原始消息路由到我們的模擬端點。

6. 測試路由

考慮到上一部分內容,我們現在來編寫一個單元測試,以探索我們的路由行為:

@SpringBootTest
@CamelSpringBootTest
class ConditionalBodyRouterUnitTest {

    @Autowired
    private ProducerTemplate template;

    @EndpointInject("mock:result-body")
    private MockEndpoint mock;

    @Test
    void whenSendBodyWithBaeldung_thenGoodbyeMessageReceivedSuccessfully() throws InterruptedException {
        mock.expectedBodiesReceived("Goodbye, Baeldung!");

        template.sendBody("direct:start-conditional", "Hello Baeldung Readers!");

        mock.assertIsSatisfied();
    }
}

如我們所見,我們的測試包含三個簡單的步驟:

  • 首先,讓我們設置一個期望,即我們的模擬端點將接收給定的消息主體
  • 然後,我們將使用我們的模板向我們的 direct:start-conditional 端點發送一條消息。請注意,我們將確保我們的消息主體包含字符串 Baeldung
  • 為了總結我們的測試,我們使用 assertIsSatisfied 方法來驗證我們在模擬端點上的初始期望是否已滿足
  • 此測試確認我們的條件路由正在正確運行。太棒了!

    請務必查看我們的以前教程,以瞭解如何為我們的 Camel 路由編寫可靠且自包含的單元測試。

    7. 構建其他條件謂詞

    到目前為止,我們已經探討了構建我們的 謂詞的一種方法,即檢查交換消息的主體。但是,還有其他幾種選項可供我們使用。

    例如,我們可以通過檢查給定消息頭的值來控制我們的條件:

    @Component
    public class ConditionalHeaderRouter extends RouteBuilder {
    
        @Override
        public void configure() throws Exception {
            
            from("direct:start-conditional-header")
                .routeId("conditional-header-route")
                .choice()
                  .when(header("fruit").isEqualTo("Apple"))
                    .setHeader("favourite", simple("Apples"))
                    .to("mock:result")
                  .otherwise()
                    .setHeader("favourite", header("fruit"))
                    .to("mock:result")
                .end();
        }
    }

    本次,我們修改了 when 方法,使其能夠查看名為 fruit 的 header 的值。 此外,還可以使用 Camel 提供的 Simple language 在 when 條件中使用。

    8. 使用 Java Bean

    此外,我們還可以使用 Camel Bean 語言,以便在我們的謂詞中利用 Java 方法調用的結果。

    首先,我們需要創建一個包含返回布爾值的 Java Bean:

    public class FruitBean {
    
        public static boolean isApple(Exchange exchange) {
            return "Apple".equals(exchange.getIn().getHeader("fruit"));
        }
    }

    我們還可以選擇將 Exchange 作為參數傳遞,以便 Camel 會自動將 Exchange 傳遞到我們的方法中。

    然後我們可以使用來自 when 塊的 FruitBean

    @Component
    public class ConditionalBeanRouter extends RouteBuilder {
    
        @Override
        public void configure() throws Exception {
            
            from("direct:start-conditional-bean")
                .routeId("conditional-bean-route")
                .choice()
                  .when(method(FruitBean.class, "isApple"))
                    .setHeader("favourite", simple("Apples"))
                    .to("mock:result")
                  .otherwise()
                    .setHeader("favourite", header("fruit"))
                     .to("mock:result")
                  .endChoice()
                .end();
        }
    }

    9. 結論

    在本文中,我們學習瞭如何在路由中根據條件進行消息路由。首先,我們創建了一個簡單的 Camel 應用,其中包含一個路由,用於檢查消息體。

    然後,我們學習了使用消息頭和 Java Bean 等技術構建路由中的謂詞(predicate)的各種方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.