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://hostname[:port][/resourceUri][?options] |
该组件必须以“ http ”或“ https ”方案开头,后跟主机名、可选端口、资源路径和查询参数。
我们可以使用URI中的httpMethod选项设置 HTTP 方法:
https://jsonplaceholder.typicode.com/posts?httpMethod=POST |
另外,我们可以在消息头中设置HTTP方法:
setHeader(Exchange.HTTP_METHOD, constant("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-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> |
然后,让我们为对“ https://jsonplaceholder.typicode.com/post ”的 POST 请求创建一个示例JSON负载:
{ "userId": 1, "title": "Java 21", "body": "Virtual Thread", } |
发送 Post 请求 首先,让我们创建一个名为PostRequestRoute 的类,它扩展了RouteBuilder类:
public class PostRequestRoute extends RouteBuilder { } |
使用 JSON 字符串发送 Post 请求 让我们定义一个向我们的虚拟服务器发送 POST 请求的路由:
from("direct:post").process(exchange -> exchange.getIn() .setBody("{\"title\":\"Java 21\",\"body\":\"Virtual Thread\",\"userId\":\ŕ\"}")) .setHeader(Exchange.CONTENT_TYPE, constant("application/json")) .to("https://jsonplaceholder.typicode.com/posts?httpMethod=POST") .to("mock:post"); |
然后,我们将请求发送到 JSONPlacehoder API。最后,我们将响应转发到模拟端点。
使用 POJO 类发送 Post 请求 但是,定义 JSON 字符串可能容易出错。为了实现更类型安全的方法,我们定义一个名为 Post 的POJO类:
public class Post { private int userId; private String title; private String body; // standard constructor, getters, setters } |
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("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"); |
接下来,我们将请求发送到虚假 API 并记录响应代码和正文。最后,我们将响应转发到模拟端点以进行测试。
测试路线 让我们编写一个测试来验证我们的路由行为。首先,让我们创建一个扩展CamelTestSupport类的测试类:
class PostRequestRouteUnitTest extends CamelTestSupport { } |
@EndpointInject("mock:result") protected MockEndpoint resultEndpoint; @Produce("direct:start") protected ProducerTemplate template; |
@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, "Java 21", "Virtual Thread")); resultEndpoint.assertIsSatisfied(); } |