写在前面,这篇文章,暂时是Apache Camel学习的最后一篇,系列文章后期更新,自己也不知道是什么时候。
Apache Camel 学习的所有代码(完整、可运行)都提交到了GitHub上面;
需要的同学请自取:https://github.com/Simba-cheng/ApacheCamelDemo
如果你觉得还不错,请点star。
我把所有学习Apache Camel找的PDF都上传了,需要的同学自取:
《Mastering Apache Camel》
《Red_Hat_Fuse-7.0-Apache_Camel_Development_Guide-en-US》
《Apache Camel Developer's Cookbook》
When you need to route messages based on the content of the message, and/or based on the headers or properties associated with the message, using Camel's Content Based Router EIP is a great way to do that. Content Based Routing and Filtering are very similar. A Content Based Router has multiple predicates, and the contained steps are performed on the firstpredicate that the message matches, or the optional otherwisestatement if none matches (similar to an if () {..} else if () {..} else {..}statement in Java). Camel's Filter EIP tests against a single predicate, executing the contained processing steps only if the message matches that predicate. The equivalent of a Filter in Java would be a single ifstatement. |
当您需要根据消息内容或基于与消息相关联的标题或属性来路由消息时,使用Camel的基于内容的路由器EIP是一种很好的方法。
基于内容的路由和过滤非常相似。
基于内容的路由器具有多个谓词,并且包含的步骤在消息匹配的firstpredicate上执行,或者如果没有匹配则执行可选的其他语句
(类似于if(){..} else if(){..} else {..}语句在Java中)。
Camel的Filter EIP针对单个谓词进行测试,仅当消息与该谓词匹配时才执行包含的处理步骤。 Java中的Filter的等价物将是单个if语句。
当需要依据消息内容选择某个路由时,可以使用choice 和 when 构造。
这些与Java中的if/else非常相似,只不过,在Camel中,等价的是 choice和when
在Java中,是这样的:
if(...){ //do something }else if(...){ //do something }else{ //do something } |
在Camel DSL中,是这样的:
from(anEndpoint) .choice() .when(someCondition).to(firstEndpoint) .when(anotherCondition).to(secondEndpoint) .otherwise() .to(thirdEndpoint) .endChoice(); |
请注意:
我们开始使用choice() - 这告诉Camel以下行将包含一些判断条件。
每种when()方法具体需要判断的条件,类似于Java中if核心。
该方法otherwise()定义了当先前when()条件均不符合时要执行的操作。
该块以.endChoice()结尾。
关键路由代码:
from("jetty:http://0.0.0.0:8282/choiceCamel").process(new Process01())
.choice()
.when(body().contains("yuanbao")).process(new Process02())
.when(body().contains("yinwenjie")).process(new Process03())
.otherwise().process(new Process04())
.endChoice();// 结束
测试结果:
服务端输出
客户端输出
关键路由代码:
from("file:./simple?noop=true")
.unmarshal().json(JsonLibrary.Jackson, Order.class)
.choice()
.when().simple("${body.type} == 'yuanbao'").process(new Process05())
.when().simple("${body.type} == 'yinwenjie'").process(new Process06())
.otherwise().process(new Process07())
.endChoice();// 结束
测试输出结果:
路由关键代码:
org.apache.camel.model.language.JsonPathExpression jsonPathExpression =
new org.apache.camel.model.language.JsonPathExpression("$.data.orgId");
jsonPathExpression.setResultType(String.class);
LOGGER.info("jsonPathExpression : " + jsonPathExpression);
from("jetty:http://0.0.0.0:8282/choiceCamel").process(new Process01())
// 将orgId属性的值存储 exchange in Message的header中,以便后续进行判断
.setHeader("orgId", jsonPathExpression)
.choice()
.when(header("orgId").isEqualTo("yuanbao")).process(new Process02())
.when(header("orgId").isEqualTo("yinwenjie")).process(new Process03())
.otherwise().process(new Process04())
.endChoice();// 结束
测试输出结果:
服务端输出结果
客户端输出结果:
路由关键代码:
/**
* 使用file组件,检查接收的文件名是否是指定的文件名
* (不过,这个也可以用file组件中的filter属性来做(效率比这个好))
*/
from("file:./simple?noop=true")
.unmarshal().json(JsonLibrary.Jackson, Order.class)
.choice()
.when(header("CamelFileName").isEqualTo("simple.json")).process(new Process05())
.when(header("CamelFileName").isEqualTo("simple2.json")).process(new Process06())
.otherwise().process(new Process07())
.endChoice();// 结束
测试输出结果:
参考来源:
《Apache Camel Developer's Cookbook》
http://camel.apache.org/content-based-router.html
https://cleverbuilder.com/articles/camel-choice-when/
http://camel.apache.org/content-based-router.html