如何在 Spring Boot 中使用 Apache Camel ProducerTemplate
1.概述
Apache Camel 讓我們可以用 Java 實作不同的企業整合模式。它提供了ProducerTemplate
接口,使我們能夠將訊息發送到 Camel 路由。使用 Spring Boot,我們可以將訊息從 REST 端點傳送到 Apache Camel 路由進行進一步處理。
在本教程中,我們將探討ProducerTemplate
的基礎知識以及它如何作為 Spring Boot 端點和 Apache Camel 路由之間的橋樑。
2. 理解ProducerTemplate
就像使用JdbcTemplate
與資料庫互動一樣, ProducerTemplate
透過將來自不同來源的訊息傳遞給 Camel 路由來與 Camel 路由互動ProducerTemplate
介面提供的兩個最常用的方法是:
-
sendBody()
– 此方法發送 inOnly 訊息。它會傳回 void,表示發送者不期望 Camel 路由的回應。 -
requestBody()
– 此方法允許我們發送 inOut 訊息,這表示當我們發送訊息時,我們會從 Camel 路由獲得回應
這兩種方法都允許我們實作 inOnly 和 inOut 訊息傳遞模式。
3. Maven依賴項
要查看ProducerTemplate
實際作用,讓我們透過向pom.xml
新增[spring-boot-starter](https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter)
和[camel-spring-boot-starter](https://mvnrepository.com/artifact/org.apache.camel.springboot/camel-spring-boot-starter)
依賴項來使用 Apache Camel 引導 Spring Boot 應用程式:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>4.12.0</version>
</dependency>
spring-boot-starter
依賴項提供了用 Java 編寫 Spring MVC 和 RESTful 應用程式的類,而camel-spring-boot-starter
依賴項提供了與 Spring Boot 的無縫整合。
4.創建路線
首先,讓我們透過在 Spring Boot 應用程式中建立一個名為CamelRoute
的類別來定義 Camel 路由:
@Component
class CamelRoute extends RouteBuilder {
@Override
public void configure() {
from("direct:start").log("Received: ${body}")
.transform(simple("Hello ${body}"));
from("direct:fileRoute").to("file://output?fileName=output.txt&fileExist=Append");
from("direct:beanRoute").bean(ProcessingBean.class, "process");
}
@Bean
public ProcessingBean processingBean() {
return new ProcessingBean();
}
}
在上面的程式碼中,我們用@Commponent
註解了該類,並定義了三個 Camel 路由。第一個路由接收一條訊息,將其記錄到控制台,並轉換原始訊息。下一個路由將訊息附加到檔案中。如果output
目錄不存在,Camel 會自動建立它。
最終的路由將訊息轉送給一個 bean 進行進一步處理。我們來看看這個 bean 類別:
class ProcessingBean {
public String process(String input) {
return "Bean processed " + input.toUpperCase();
}
}
在這裡,bean 透過將訊息轉換為大寫來處理訊息並傳回新的訊息正文。
5. 控制器和測試類
接下來,讓我們建立一個控制器類別並注入ProducerTemplate
介面:
@RestController
public class ProducerTemplateController {
@Autowired
private ProducerTemplate producerTemplate;
}
我們現在可以使用sendBody()
和requestBody()
方法分別傳送 inOnly 或 inOut 訊息。
另外,讓我們建立一個名為ProducerTemplateIntegrationTest
的測試類別:
@CamelSpringBootTest
@SpringBootTest(classes = ProducerTemplateApplication.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class ProducerTemplateIntegrationTest {
@Autowired
private ProducerTemplateController producerTemplateController;
private static final String TEST_MESSAGE = "TestMessage";
private static final Path OUTPUT_FILE = Paths.get("output/output.txt");
// ...
}
在上面的程式碼中,我們用@SpringBootTest
註解測試類,並指定要測試的應用程式。最後,我們定義兩個變數來儲存訊息和檔案路徑。
5.1. 發送訊息到direct:start
Route
讓我們建立一個向我們的第一個 Camel 路由發送訊息的端點:
@GetMapping("/send/simple/{message}")
public String sendSimpleMessage(@PathVariable String message) {
String response = producerTemplate.requestBody("direct:start", message, String.class);
return response;
}
上面的端點接受以 URL 路徑變數形式傳遞的message
。接下來,我們向direct:start
路由發送一條message
。由於我們在producerTemplate
上呼叫了requestBody()
,因此這遵循了 inOut 訊息模式。接下來,我們從 Camel 路由回傳轉換後的訊息。
讓我們寫一個測試來驗證回應:
@Test
void givenMessage_whenSendingSimpleMessage_thenReturnsProcessedMessage() {
String inputMessage = TEST_MESSAGE;
String response = producerTemplateController.sendSimpleMessage(inputMessage);
assertNotNull(response, "Response should not be null");
assertEquals("Hello " + inputMessage, response);
}
在上面的程式碼中,我們在producerTemplateController
實例上呼叫了sendSimpleMessage()
方法。然後,我們驗證回應是否為null
。最後,我們確認響應是否與預期響應相符。
5.2. 傳送訊息到direct:fileRoute
路由
此外,讓我們在控制器類別中編寫一個新的 Spring Boot 端點:
@GetMapping("/send/file/{message}")
public String sendToFile(@PathVariable String message) {
producerTemplate.sendBody("direct:fileRoute", message + "\n");
return "Message appended to output.txt";
}
在這裡,我們將來自端點的message
附加到文件中。在本例中,我們使用了sendBody()
方法,這表示我們不期望從 Camel 路由獲得回應,因為它使用了 inOnly 訊息模式。
接下來,讓我們編寫一個測試來確認訊息是否附加到文件中:
@Test
void givenMessage_whenSendingToFile_thenFileContainsMessage() throws IOException {
String inputMessage = TEST_MESSAGE;
String response = producerTemplateController.sendToFile(inputMessage);
assertEquals("Message appended to output.txt", response);
assertTrue(Files.exists(OUTPUT_FILE));
String fileContent = Files.readString(OUTPUT_FILE);
assertTrue(fileContent.contains(inputMessage));
}
在上面的測試中,我們確定輸出檔案存在並且包含預期的訊息。
5.3. 發送訊息到direct:beanRoute
路由
最後,讓我們寫一個控制器方法,向direct:beanRoute
路由發送一條訊息:
@GetMapping("/send/bean/{message}")
public String sendToBean(@PathVariable String message) {
String response = producerTemplate.requestBody("direct:beanRoute", message, String.class);
return response;
}
上面的端點接收一條傳遞到 Camel 路由的訊息。 Camel 路由處理該訊息並傳回處理後的訊息。
讓我們透過編寫測試來確認返回了正確的回應:
@Test
void givenMessage_whenSendingToBean_thenReturnsUppercaseMessage() {
String inputMessage = TEST_MESSAGE;
String response = producerTemplateController.sendToBean(inputMessage);
assertNotNull(response);
assertEquals("Bean processed " + inputMessage.toUpperCase(), response);
}
sendToBean()
方法向 bean 發送一條訊息,該 bean 會將其轉換為大寫。我們確認返回了預期的響應。
6. 結論
在本文中,我們學習如何在 Spring Boot 和 Apache Camel 應用程式中使用ProducerTemplate
。此外,我們也透過實際範例示範如何從 REST 端點向 Camel 路由發送 inOnly 和 inOut 訊息。
與往常一樣,範例的完整原始程式碼可在 GitHub 上找到。