如何在Camel中Post一個請求?

banq發表於2024-07-20


Apache Camel是一個強大的開源整合框架。它提供了一套成熟的元件來與各種協議和系統進行互動,包括HTTP。

在本文中,我們將學習如何使用 Apache Camel 向外部伺服器發出 POST 請求。我們首先定義一個使用 JSON 字串和 POJO 傳送 POST 請求的路由。

此外,我們還了解了如何使用 HTTP 元件與外部 API 進行通訊。最後,我們編寫了一個單元測試來驗證我們的路由行為。

在本教程中,我們將探索 Apache Camel HTTP 元件並演示如何向JSONPlaceholder(一個用於測試和原型設計的免費虛假 API)發起 POST 請求。

Apache Camel HTTP 元件
Apache Camel HTTP 元件提供與外部 Web 伺服器通訊的功能。它支援各種 HTTP 方法,包括 GET、POST、PUT、DELETE 等。

預設情況下,HTTP 元件使用埠 80(用於 HTTP)和埠 443(用於 HTTPS)。以下是 HTTP 元件 URI 的一般語法:

http:<font>//hostname[:port][/resourceUri][?options]<i>

該元件必須以“ http ”或“ https ”方案開頭,後跟主機名、可選埠、資源路徑和查詢引數。

我們可以使用URI中的httpMethod選項設定 HTTP 方法:

https:<font>//jsonplaceholder.typicode.com/posts?httpMethod=POST<i>

另外,我們可以在訊息頭中設定HTTP方法:

setHeader(Exchange.HTTP_METHOD, constant(<font>"POST"))

設定 HTTP 方法對於成功發起請求至關重要。

專案設定
首先,讓我們將camel-core和camel-test-jnit5依賴項新增到pom.xml:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-core</artifactId>
    <version>4.6.0</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-test-junit5</artifactId>
    <version>4.6.0</version>
</dependency>

camel -core依賴項提供了系統整合的核心類。其中一個重要類是用於建立路由的RouteBuilder。camel-test-junit5 提供了使用JUnit 5測試 Camel 路由的支援。

接下來,讓我們將camel-jackson和camel-http依賴項新增到pom.xml中:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jackson</artifactId>
    <version>4.6.0</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-http</artifactId>
    <version>4.6.0</version>
</dependency>

camel -http 依賴項為 HTTP 元件與外部伺服器通訊提供支援。此外,我們新增了camel-jackson依賴項,以便使用 Jackson 進行JSON序列化和反序列化。

然後,讓我們為對“ https://jsonplaceholder.typicode.com/post ”的 POST 請求建立一個示例JSON負載:

{
  <font>"userId": 1,
 
"title": "Java 21",
 
"body": "Virtual Thread",
}

這裡,有效負載包含userId、title和body。我們期望端點在成功建立新帖子時返回 HTTP 狀態程式碼 201。

傳送 Post 請求
首先,讓我們建立一個名為PostRequestRoute 的類,它擴充套件了RouteBuilder類:

public class PostRequestRoute extends RouteBuilder { 
}

RouteBuilder類允許我們重寫configure()方法來建立路線。

使用 JSON 字串傳送 Post 請求
讓我們定義一個向我們的虛擬伺服器傳送 POST 請求的路由:

from(<font>"direct:post").process(exchange -> exchange.getIn()
  .setBody(
"{\&#34title\&#34:\&#34Java 21\&#34,\&#34body\&#34:\&#34Virtual Thread\&#34,\&#34userId\&#34:\&#341\&#34}"))
  .setHeader(Exchange.CONTENT_TYPE, constant(
"application/json"))
  .to(
"https://jsonplaceholder.typicode.com/posts?httpMethod=POST")
  .to(
"mock:post");

在這裡,我們定義一個路由並將有效負載設定為 JSON 字串。setBody ()  body方法接受 JSON 字串作為引數。此外,我們使用httpMethod選項將 HTTP 方法設定為 POST。

然後,我們將請求傳送到 JSONPlacehoder API。最後,我們將響應轉發到模擬端點。

使用 POJO 類傳送 Post 請求
但是,定義 JSON 字串可能容易出錯。為了實現更型別安全的方法,我們定義一個名為 Post 的POJO類:

public class Post {
    private int userId;
    private String title;
    private String body;
    <font>// standard constructor, getters, setters<i>
}

接下來,讓我們修改路由以使用 POJO 類:

from(<font>"direct:start").process(exchange -> exchange.getIn()
  .setBody(new Post(1,
"Java 21", "Virtual Thread"))).marshal().json(JsonLibrary.Jackson)
  .setHeader(Exchange.HTTP_METHOD, constant(
"POST"))
  .setHeader(Exchange.CONTENT_TYPE, constant(
"application/json"))
  .to(
"https://jsonplaceholder.typicode.com/posts")
  .process(exchange -> log.info(
"The HTTP response code is: {}", exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE)))
  .process(exchange -> log.info(
"The response body is: {}", exchange.getIn().getBody(String.class)))
  .to(
"mock:result");

在這裡,我們從名為start的直接端點開始。然後,我們建立一個Post例項並將其設定為請求主體。此外,我們使用Jackson將 POJO 編組為 JSON。

接下來,我們將請求傳送到虛假 API 並記錄響應程式碼和正文。最後,我們將響應轉發到模擬端點以進行測試。

測試路線
讓我們編寫一個測試來驗證我們的路由行為。首先,讓我們建立一個擴充套件CamelTestSupport類的測試類:

class PostRequestRouteUnitTest extends CamelTestSupport {
}

然後,讓我們建立一個模擬端點和生產者模板:

@EndpointInject(<font>"mock:result")
protected MockEndpoint resultEndpoint;
@Produce(
"direct:start")
protected ProducerTemplate template;

接下來,讓我們重寫createRouteBuilder()方法以使用PostRequesteRoute:

@Override
protected RouteBuilder createRouteBuilder() {
    return new PostRequestRoute();
}

最後我們來寫一個測試方法:

@Test
void whenMakingAPostRequestToDummyServer_thenAscertainTheMockEndpointReceiveOneMessage() throws Exception {
    resultEndpoint.expectedMessageCount(1);
    resultEndpoint.message(0).header(Exchange.HTTP_RESPONSE_CODE)
      .isEqualTo(201);
    resultEndpoint.message(0).body()
      .isNotNull();
    template.sendBody(new Post(1, <font>"Java 21", "Virtual Thread"));
    resultEndpoint.assertIsSatisfied();
}

在上面的程式碼中,我們定義了對模擬端點的期望,並使用template.sendBody()方法傳送請求。最後,我們確定模擬端點的期望得到滿足。

相關文章