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必须以http
或https
开头,后跟主机名、可选端口、资源路径和查询参数。
可通过以下两种方式设置HTTP方法:
- 在URI中使用
httpMethod
选项:https://jsonplaceholder.typicode.com/posts?httpMethod=POST
- 在消息头中设置:
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请求
创建继承RouteBuilder
的PostRequestRoute
类:
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");
关键点:
setBody()
方法直接接收JSON字符串- 通过URI参数
httpMethod=POST
指定请求方法 - 最后将响应转发到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");
关键改进:
- 创建
Post
实例作为请求体 - 使用Jackson将POJO自动转换为JSON
- 记录响应码和响应体
- 最终转发到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();
}
测试验证点:
- mock端点接收1条消息
- 响应状态码为201
- 响应体非空
- 通过
template.sendBody()
发送请求
6. 总结
本文演示了使用Apache Camel发送POST请求的两种方式:
- 直接使用JSON字符串(简单粗暴但易出错)
- 使用POJO+Jackson(类型安全推荐方案)
关键收获:
- HTTP组件的URI配置技巧
- 消息头设置HTTP方法的方式
- POJO与JSON的自动转换
- 路由测试的最佳实践
完整源码可在GitHub仓库获取。