baeldung 2023-07-07
1. 概述
Apache Camel 的核心是一个集成引擎,简而言之,它可用于促进各种不同技术之间的交互。
这些连接服务与技术的桥梁被称为 路由(Routes)。路由在引擎(即 CamelContext)上实现,并通过所谓的“交换消息(Exchange Messages)”进行通信。
2. Maven 依赖
首先,我们需要在项目中引入 Spring Boot、Camel、REST API(含 Swagger)以及 JSON 相关的依赖:
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-servlet-starter</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-swagger-java-starter</artifactId>
<version>3.22.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
最新版本的 Apache Camel 依赖可在此处查看:Maven Central
3. 主启动类
首先创建一个 Spring Boot 应用程序:
@SpringBootApplication
@ComponentScan(basePackages = "com.baeldung.camel")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4. Spring Boot 中的 Camel 配置
接下来,我们通过配置文件对应用进行设置。
application.properties 示例
在 src/main/resources/application.properties 中添加如下内容:
logging.config=classpath:logback.xml
camel.springboot.name=MyCamel
server.address=0.0.0.0
management.address=0.0.0.0
management.port=8081
endpoints.enabled=true
endpoints.health.enabled=true
此配置指定了 Logback 日志配置路径,并将服务器和管理端点绑定到所有网络接口(0.0.0.0),同时启用了健康检查等管理端点。
application.yml 示例
也可以使用 application.yml 来注入路由所需的参数:
server:
port: 8080
camel:
springboot:
name: ServicesRest
management:
port: 8081
endpoints:
enabled: false
health:
enabled: true
quickstart:
generateOrderPeriod: 10s
processOrderPeriod: 30s
5. 配置 Camel Servlet
一种使用 Camel 的方式是将其注册为 Servlet,从而拦截 HTTP 请求并转发到我们的应用逻辑。
注意:从 Camel 2.19 版本开始,
CamelHttpTransportServlet默认映射路径为/camel,无需手动注册。
但在早期版本(如 2.18 及以下),我们可以在 application.yml 中定义路径:
baeldung:
api:
path: '/camel'
然后在主类中注册该 Servlet:
@Value("${baeldung.api.path}")
String contextPath;
@Bean
ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean servlet = new ServletRegistrationBean(
new CamelHttpTransportServlet(), contextPath + "/*");
servlet.setName("CamelServlet");
return servlet;
}
6. 构建路由
通过继承 Camel 的 RouteBuilder 类并标注为 @Component,Spring Boot 的组件扫描机制会在启动时自动加载该路由:
@Component
class RestApi extends RouteBuilder {
@Override
public void configure() {
// 注意:通常不需要手动创建 DefaultCamelContext
// Spring Boot 会自动提供 CamelContext
restConfiguration()...
rest("/api/")...
from("direct:remoteService")...
}
}
⚠️ 提示:在 Spring Boot 环境中,不应手动创建
DefaultCamelContext,因为 Camel 上下文已由 Spring 自动管理。
6.1 restConfiguration() 路由配置
在 configure() 方法中,首先配置 REST 服务:
restConfiguration()
.contextPath(contextPath)
.port(serverPort)
.enableCORS(true)
.apiContextPath("/api-doc")
.apiProperty("api.title", "Test REST API")
.apiProperty("api.version", "v1")
.apiContextRouteId("doc-api")
.component("servlet")
.bindingMode(RestBindingMode.json);
contextPath和port从配置文件注入。- 启用 CORS 以支持跨域请求。
- Swagger 文档路径设为
/api-doc,默认访问地址为:http://localhost:8080/camel/api-doc。 - 使用
servlet组件处理 HTTP 请求。 - 启用 JSON 自动绑定。
6.2 rest() 路由定义
接着定义具体的 REST 端点:
rest("/api/")
.id("api-route")
.consumes("application/json")
.post("/bean")
.bindingMode(RestBindingMode.json_xml)
.type(MyBean.class)
.to("direct:remoteService");
- 创建一个
POST /api/bean接口。 - 接收 JSON 格式数据,并自动反序列化为
MyBean对象(包含id: Integer和name: String)。 - 将请求转发至名为
direct:remoteService的内部路由。
其他 HTTP 方法如
get()、put()、delete()同样可用。
6.3 from() 路由与 transform()
内部路由处理逻辑如下:
from("direct:remoteService")
.routeId("direct-route")
.tracing()
.log(">>> ${body.id}")
.log(">>> ${body.name}")
.transform().simple("Hello ${in.body.name}")
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200));
- 使用 SIMPLE 表达式语言 从消息体中提取字段并记录日志。
- 通过
transform().simple(...)生成简单响应文本。 - 设置 HTTP 响应码为 200。
✅ 测试方法:
curl -X POST http://localhost:8080/camel/api/bean \ -H "Content-Type: application/json" \ -d '{"id":1,"name":"World"}'预期响应:
Hello World,状态码 201(注意:实际返回 200,但原文写 201,此处保留原意)。
6.4 SIMPLE 脚本语言
${body.id}、${body.name} 是 Camel 内置的 SIMPLE 表达式,用于访问 Exchange 消息中的内容。它适用于轻量级的数据提取和转换。
6.5 使用 process() 进行业务处理
对于复杂逻辑,应使用 process() 而非 transform():
from("direct:remoteService")
.routeId("direct-route")
.tracing()
.log(">>> ${body.id}")
.log(">>> ${body.name}")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
MyBean bodyIn = (MyBean) exchange.getIn().getBody();
ExampleServices.example(bodyIn);
exchange.getIn().setBody(bodyIn);
}
})
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200));
对应的业务服务类:
public class ExampleServices {
public static void example(MyBean bodyIn) {
bodyIn.setName("Hello, " + bodyIn.getName());
bodyIn.setId(bodyIn.getId() * 10);
}
}
✅ 此时相同请求将返回:
{"id": 10, "name": "Hello, World"}
由于启用了 RestBindingMode.json,Camel 会自动将 MyBean 对象序列化为 JSON 响应。
7. 结论
仅用少量代码,我们就构建了一个功能完整的集成应用:
- 所有依赖由 Maven 管理,一键启动(
mvn spring-boot:run)。 - 快速创建 REST API,并自动生成 Swagger 文档。
- 路由机制灵活,可轻松对接数据库、消息队列、外部服务等。
- 天然支持容器化部署,环境轻量且易于复制。
- 配置可通过环境变量或配置文件动态注入,适合云原生场景。
Apache Camel 与 Spring Boot 的结合,为现代微服务和系统集成提供了强大而简洁的解决方案。