13.2. 如何中断表达式语言
先决条件
在使用特定的表达式语言之前,您必须确保 classpath 上有所需的 JAR 文件。如果 Apache Camel 内核中没有包括您要使用的语言,您必须将相关的 JAR 添加到 classpath 中。
如果使用 Maven 构建系统,只需将相关依赖项添加到 POM 文件中来修改 build-time classpath。例如,如果要使用 Ruby 语言,请在 POM 文件中添加以下依赖项:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-groovy</artifactId> <!-- Use the same version as your Camel core version --> <version>${camel.version}</version> </dependency>
如果您要在红帽 Fuse OSGi 容器中部署应用程序,您还需要确保安装了相关的语言功能(功能在对应的 Maven 工件后被命名)。例如,要在 OSGi 容器中使用 Groovy 语言,您必须首先通过输入以下 OSGi 控制台命令来安装 camel-groovy
功能:
karaf@root> features:install camel-groovy
如果您在路由中使用表达式或 predicate,请使用 resource:classpath:path
或 resource:file:path
将值引用为外部资源。例如: resource:classpath:com/foo/myscript.groovy
。
Camel on EAP 部署
camel-groovy
组件由 EAP 上的 Camel (Wildfly Camel)框架支持,该框架在 Red Hat JBoss Enterprise Application Platform (JBoss EAP)容器上提供了简化的部署模型。
调用方法
如 表 13.1 “表达式和 predicates 语言” 所示,调用表达式语言有几个不同的语法,具体取决于所用的上下文。您可以调用表达式语言:
作为静态方法
大多数语言都定义了静态方法,可在任何 上下文中使用 org.apache.camel.Expression
类型或 org.apache.camel.Predicate
类型。静态方法使用字符串表达式(或 predicate)作为其参数,并返回 Expression
对象(通常是 Predicate
对象)。
例如,要实施以 XML 格式处理消息的基于内容的路由器,您可以根据 /order/address/countryCode
元素的值路由消息,如下所示:
from("SourceURL") .choice .when(xpath("/order/address/countryCode = 'us'")) .to("file://countries/us/") .when(xpath("/order/address/countryCode = 'uk'")) .to("file://countries/uk/") .otherwise() .to("file://countries/other/") .to("TargetURL");
作为流畅的 DSL 方法
Java fluent DSL 支持另一种调用表达式语言样式。您可以向 DSL 命令的子层提供表达式,而不是提供表达式作为企业集成模式(EIP)的参数。例如,您可以将表达式调用为 filter (xpath ("Expression")
,而不是调用 XPath 表达式,而是以 filter ().xpath ("Expression")
调用表达式。
例如,在这种调用方式中,上述基于内容的路由器可以重新实施,如下所示:
from("SourceURL") .choice .when().xpath("/order/address/countryCode = 'us'") .to("file://countries/us/") .when().xpath("/order/address/countryCode = 'uk'") .to("file://countries/uk/") .otherwise() .to("file://countries/other/") .to("TargetURL");
作为 XML 元素
您还可以通过将表达式字符串放在相关 XML 元素中,在 XML 中调用表达式语言。
例如,在 XML 中调用 XPath 的 XML 元素为 xpath
(属于标准的 Apache Camel 命名空间)。您可以在基于 XML DSL 内容的路由器中使用 XPath 表达式,如下所示:
<from uri="file://input/orders"/> <choice> <when> <xpath>/order/address/countryCode = 'us'</xpath> <to uri="file://countries/us/"/> </when> <when> <xpath>/order/address/countryCode = 'uk'</xpath> <to uri="file://countries/uk/"/> </when> <otherwise> <to uri="file://countries/other/"/> </otherwise> </choice>
或者,您可以使用 language
元素指定语言表达式,您可以在其中在语言属性中指定 语言名称
。例如,您可以使用 language
元素定义 XPath 表达式,如下所示:
<language language="xpath">/order/address/countryCode = 'us'</language>
作为注解
语言注解在 bean 集成上下文中使用。该注释提供了一种便捷的方式,可以从消息或标头提取信息,然后将提取的数据注入 bean 的方法。
例如,考虑 bean、myBeanProc
,它作为 filter ()
EIP 的 predicate 调用。如果 bean 的 checkCredentials
方法返回 true
,则允许消息继续;但如果方法返回 false
,则过滤器阻止消息。过滤器模式实施如下:
// Java MyBeanProcessor myBeanProc = new MyBeanProcessor(); from("SourceURL") .filter().method(myBeanProc, "checkCredentials") .to("TargetURL");
MyBeanProcessor
类的实现利用 @XPath
注释,从底层 XML 消息中提取
,如下所示:
用户名和密码
// Java import org.apache.camel.language.XPath; public class MyBeanProcessor { boolean void checkCredentials( @XPath("/credentials/username/text()") String user, @XPath("/credentials/password/text()") String pass ) { // Check the user/pass credentials... ... } }
@XPath
注释仅在它被注入的参数之前放置。注意 XPath 表达式如何 显式 选择文本节点,方法是向路径附加 /text ()
,这样可确保仅选择元素的内容,而不是弹出标签。
作为 Camel 端点 URI
使用 Camel 语言组件,您可以在端点 URI 中调用受支持的语言。有两种替代语法:
要调用存储在文件中的语言脚本(或其他由 Scheme
定义的资源类型),请使用以下 URI 语法:
language://LanguageName:resource:Scheme:Location[?Options]
其中方案可以是 文件:
、classpath:
或 http:
。
例如,以下路由从 classpath 执行 mysimplescript.txt
:
from("direct:start") .to("language:simple:classpath:org/apache/camel/component/language/mysimplescript.txt") .to("mock:result");
要调用嵌入的语言脚本,请使用以下 URI 语法:
language://LanguageName[:Script][?Options]
例如,要运行存储在脚本字符串中的 Simple 语言 脚本
:
String script = URLEncoder.encode("Hello ${body}", "UTF-8"); from("direct:start") .to("language:simple:" + script) .to("mock:result");
有关语言组件的更多详细信息,请参阅 Apache Camel 组件参考指南 中的 语言。