1. 概述
Apache Camel 本质上是一个集成引擎,简单来说,它能帮助我们在各种异构技术之间建立连接。这些服务和技术之间的桥梁被称为路由(Routes)。路由在引擎(即 CamelContext)上实现,通过所谓的"交换消息"进行通信。
2. Maven 依赖
首先需要添加 Spring Boot、Camel、Swagger 和 JSON 相关的依赖:
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-servlet-starter</artifactId>
<version>3.21.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId>
<version>3.21.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-swagger-java-starter</artifactId>
<version>3.21.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.21.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
最新版 Apache Camel 依赖可在 Maven 仓库 查找。
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 配置
通过配置文件进行应用设置。在 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
:
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 请求。在 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;
}
⚠️ 注意:Camel 2.19+ 版本后,CamelServlet
默认路径为 /camel
,此配置可省略。
6. 构建路由
通过继承 RouteBuilder
创建路由类,并添加 @Component
注解:
@Component
class RestApi extends RouteBuilder {
@Override
public void configure() {
CamelContext context = new DefaultCamelContext();
restConfiguration()...
rest("/api/")...
from("direct:remoteService")...
}
}
核心要点:
- Camel 必须有
CamelContext
实例(消息存储核心) DefaultCamelContext
适用于基础场景
6.1. restConfiguration() 路由
配置 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)
关键配置:
- ✅ 注入 YAML 中的上下文路径和端口
- ✅ 启用 CORS 跨域支持
- ✅ 自动生成 Swagger 文档(访问
http://localhost:8080/camel/api-doc
) - ✅ 设置 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");
解析:
id
:路由在 CamelContext 中的唯一标识consumes
:指定 MIME 类型post()
:创建 POST 接口(支持get()
/put()
/delete()
)type()
:定义请求体类型(需是标准 Java Bean)to()
:桥接到其他路由(通过direct:
前缀匹配)
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));
执行流程:
- 接收
rest().to()
转发的消息 - 记录请求体中的
id
和name
- 使用
transform()
转换响应内容 - 设置 HTTP 状态码
测试方法:
# 启动应用
mvn spring-boot:run
# 发送 POST 请求
curl -X POST http://localhost:8080/camel/api/bean \
-H "Content-Type: application/json" \
-d '{"id": 1, "name": "World"}'
预期响应:状态码 201,响应体 Hello, World
6.4. SIMPLE 脚本语言
Camel 内置的 SIMPLE 表达式语言:
- ✅ 通过
${}
占位符访问消息属性 - ✅ 示例:
${body.id}
获取请求体字段 - ✅ 支持简单转换(如
transform().simple()
)
6.5. from() 路由与 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": 1, "name": "World"}
- 响应:
{"id": 10, "name": "Hello, World"}
(状态码 201)
7. 总结
通过少量代码即可构建功能完整的集成应用:
- ✅ 依赖管理和启动自动化
- ✅ 支持异构技术集成
- ✅ 容器友好(轻量级,易扩展)
扩展资源:
完整示例代码见 GitHub 仓库。