使用 camel-jackson 解析 JSON 數組

Jackson,Spring Boot
Remote
1
09:48 PM · Nov 30 ,2025

1. 概述

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

通常在通過 Camel 進行消息路由時,我們希望使用許多支持的插件式 數據格式。 鑑於 JSON 在許多現代 API 和數據服務中很受歡迎,因此它成為一種常見的選擇。

在本教程中,我們將探討幾種將 JSON 數組解析為 Java 對象列表的方法,使用 camel-jackson 組件。

2. 依賴項

首先,我們將 camel-jackson-starter 依賴項添加到我們的 pom.xml

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-jackson-starter</artifactId>
    <version>3.21.0</version>
</dependency>

然後,我們還將 camel-test-spring-junit5 依賴項專門用於我們的單元測試:

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

3. 結果域類在整個教程中,我們將使用幾個輕量級POJO對象來建模我們的結果域。

讓我們定義一個具有idname的類來表示一個結果:

public class Fruit {

    private String name;
    private int id;

    // standard getter and setters
}

接下來,我們將定義一個包含Fruit對象的容器:

public class FruitList {

    private List<Fruit> fruits;

    public List<Fruit> getFruits() {
        return fruits;
    }

    public void setFruits(List<Fruit> fruits) {
        this.fruits = fruits;
    }
}

在接下來的幾個部分中,我們將看到如何將表示結果對象的JSON字符串反序列化到這些域類中最終我們想要的是一個類型為List<Fruit> 的變量,以便我們可以使用它.

4. Unmarshalling a JSON FruitList

在第一個示例中,我們將一個簡單的水果列表表示為 JSON 格式:

{
    "fruits": [
        {
            "id": 100,
            "name": "Banana"
        },
        {
            "id": 101,
            "name": "Apple"
        }
    ]
}

最重要的是,我們應該強調的是,這個 JSON 代表了一個包含一個名為 fruits 的屬性的對象

現在,讓我們為執行反序列化設置我們的 Apache Camel 路由:

@Bean
RoutesBuilder route() {
    return new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            from("direct:jsonInput").unmarshal(new JacksonDataFormat(FruitList.class))
              .to("mock:marshalledObject");
        }
    };
}

在示例中,我們使用名為 direct 的端點,名稱為 jsonInput。接下來,我們調用 unmarshal 方法,該方法將接收到的每個消息主體(來自 Camel 交換)反序列化為指定的格式。

我們正在使用 JacksonDataFormat 類,自定義反序列化類型為 FruitList

這本質上是一個圍繞 Jackon ObjectMapper 的簡單包裝器,並且允許我們向和從 JSON 中進行序列化。

最後,我們將 unmarshal 方法的結果發送到名為 marshalledObjectmock 端點。正如我們即將看到的,這正是我們用來測試路由是否正常工作的方式。

讓我們來走過我們測試中的關鍵部分,以瞭解發生了什麼:

  • 首先,我們首先添加了 @CamelSpringBootTest 註解,這是一個有用的註解,用於使用 Spring Boot 測試 Camel。
  • 然後,我們使用 @EndpointInject 註解注入 MockEndpoint。此註解允許我們在不手動從 Camel 上下文中查找它們的情況下設置 mock 端點。在此處,我們將 mock:marshalledObject 設置為 Camel 端點的 URI。它指向一個名為 marshalledObjectmock 端點。它指向一個名為 marshalledObjectmock 端點。
  • 之後,我們設置測試期望。我們的 mock 端點應接收一條消息,並且消息類型應為 FruitList
  • 現在我們準備好將 JSON 輸入文件作為 String 發送到 direct 端點。我們使用 ProducerTemplate 類將消息發送到端點。
  • 在檢查我們的 mock 期望是否已滿足後,我們可以檢索 FruitList 並檢查其內容是否符合預期。

此測試確認我們的路由正在正常工作,並且我們的 JSON 正在被反序列化為預期的格式。太棒了!

5. 將JSON Fruit數組反序列化

另一方面,我們可能不想使用容器對象來存儲我們的Fruit對象。我們可以修改我們的JSON以直接存儲一個水果數組:

[
    {
        "id": 100,
        "name": "Banana"
    },
    {
        "id": 101,
        "name": "Apple"
    }
]

這次,我們的路由幾乎與之前相同,但我們將其設置成專門處理JSON數組:

@Bean
RoutesBuilder route() {
    return new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            from("direct:jsonInput").unmarshal(new ListJacksonDataFormat(Fruit.class))
              .to("mock:marshalledObject");
        }
    };
}

正如我們所見,與之前示例唯一的區別是我們正在使用ListJacksonDataFormat類,並使用自定義的反序列化類型Fruit這是一種Jackson數據格式類型,我們可以用來處理列表

同樣,我們的單元測試非常相似:

@Test
public void givenJsonFruitArray_whenUnmarshalled_thenSuccess() throws Exception {
    mock.setExpectedMessageCount(1);
    mock.message(0).body().isInstanceOf(List.class);

    String json = readJsonFromFile("/json/fruit-array.json");
    template.sendBody("direct:jsonInput", json);
    mock.assertIsSatisfied();

    @SuppressWarnings("unchecked")
    List<Fruit> fruitList = mock.getReceivedExchanges().get(0).getIn().getBody(List.class);
    assertNotNull("Fruit lists should not be null", fruitList);

    assertEquals("There should be two fruits", 2, fruitList.size());

    Fruit fruit = fruitList.get(0);
    assertEquals("Fruit name", "Banana", fruit.getName());
    assertEquals("Fruit id", 100, fruit.getId());

    fruit = fruitList.get(1);
    assertEquals("Fruit name", "Apple", fruit.getName());
    assertEquals("Fruit id", 101, fruit.getId());
}

然而,與上一節中看到的測試相比,有兩個微妙的差異:

  • 我們首先設置mock期望包含一個帶有List.class正文的期望。
  • 當我們以List.class的形式檢索消息正文時,我們會收到有關類型安全性的標準警告——因此使用了@SuppressWarnings(“unchecked”).

6. 結論

在本文中,我們看到了兩種簡單的JSON數組反序列化方法,即使用camel消息路由和camel-jackson組件。這兩種方法的主要區別在於,JacksonDataFormat反序列化到對象類型,而ListJacksonDataFormat則反序列化到列表類型。

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

發佈 評論

Some HTML is okay.