1. 概述

Apache Camel是一个强大的开源集成框架,提供了一套成熟的组件用于与各种协议和系统交互,包括HTTP。

本文将深入探讨Apache Camel的HTTP组件,演示如何向JSONPlaceholder(一个免费的测试和原型设计API)发送POST请求。

2. Apache Camel HTTP组件

HTTP组件提供与外部Web服务器通信的功能,支持GET、POST、PUT、DELETE等多种HTTP方法。

⚠️ 默认情况下,HTTP组件使用80端口(HTTP)和443端口(HTTPS)。组件URI的通用语法如下:

http://hostname[:port][/resourceUri][?options]

URI必须以httphttps开头,后跟主机名、可选端口、资源路径和查询参数。

可通过以下两种方式设置HTTP方法:

  1. 在URI中使用httpMethod选项:
    https://jsonplaceholder.typicode.com/posts?httpMethod=POST
    
  2. 在消息头中设置:
    setHeader(Exchange.HTTP_METHOD, constant("POST"))
    

✅ 正确设置HTTP方法是成功发起请求的关键。

3. 项目搭建

首先添加核心依赖到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路由。

接着添加HTTP和Jackson依赖:

<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提供与外部服务器通信的能力,camel-jackson用于JSON序列化/反序列化。

准备POST请求的JSON示例载荷:

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

成功创建新文章后,接口应返回HTTP状态码201。

4. 发送POST请求

创建继承RouteBuilderPostRequestRoute类:

public class PostRequestRoute extends RouteBuilder { 
}

RouteBuilder允许通过重写configure()方法创建路由。

4.1 使用JSON字符串发送POST请求

定义发送POST请求的路由:

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

关键点:

  1. setBody()方法直接接收JSON字符串
  2. 通过URI参数httpMethod=POST指定请求方法
  3. 最后将响应转发到mock端点用于测试

4.2 使用POJO类发送POST请求

直接拼接JSON字符串容易出错,推荐使用POJO方式。定义Post类:

public class Post {
    private int userId;
    private String title;
    private String body;

    // 标准构造方法、getter和setter
}

修改路由使用POJO:

from("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("HTTP响应码: {}", exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE)))
    .process(exchange -> log.info("响应体: {}", exchange.getIn().getBody(String.class)))
    .to("mock:result");

关键改进:

  1. 创建Post实例作为请求体
  2. 使用Jackson将POJO自动转换为JSON
  3. 记录响应码和响应体
  4. 最终转发到mock端点

5. 测试路由

创建测试类继承CamelTestSupport

class PostRequestRouteUnitTest extends CamelTestSupport {
}

注入mock端点和生产者模板:

@EndpointInject("mock:result")
protected MockEndpoint resultEndpoint;

@Produce("direct:start")
protected ProducerTemplate template;

重写createRouteBuilder()方法:

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

编写测试方法:

@Test
void whenSendPostRequest_thenVerifyResponse() 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, "Java 21", "Virtual Thread"));

    resultEndpoint.assertIsSatisfied();
}

测试验证点:

  1. mock端点接收1条消息
  2. 响应状态码为201
  3. 响应体非空
  4. 通过template.sendBody()发送请求

6. 总结

本文演示了使用Apache Camel发送POST请求的两种方式:

  1. 直接使用JSON字符串(简单粗暴但易出错)
  2. 使用POJO+Jackson(类型安全推荐方案)

关键收获:

  • HTTP组件的URI配置技巧
  • 消息头设置HTTP方法的方式
  • POJO与JSON的自动转换
  • 路由测试的最佳实践

完整源码可在GitHub仓库获取。


原始标题:How to Send a Post Request in Camel | Baeldung