这是用户在 2024-3-29 8:19 为 https://camel.apache.org/components/4.4.x/languages/java-language.html 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?

Java

Since Camel 4.3 自从骆驼 4.3 版本以来

The Java language (uses jOOR library to compile Java code) allows using Java code in your Camel expression, with some limitations.
Java 语言(使用 jOOR 库编译 Java 代码)允许在 Camel 表达式中使用 Java 代码,但有一些限制。

The jOOR library integrates with the Java compiler and performs runtime compilation of Java code.
jOOR 库与 Java 编译器集成,并对 Java 代码进行运行时编译。

Java Options JAVA 选项

The Java language supports 4 options, which are listed below.
Java 语言支持以下 4 个选项。

Name 姓名 Default 默认 Java Type Java 类型 Description 描述

preCompile 预编译

true

Boolean

Whether the expression should be pre compiled once during initialization phase. If this is turned off, then the expression is reloaded and compiled on each evaluation.
是否应在初始化阶段预编译表达式。如果关闭此选项,则在每次评估时重新加载和编译表达式。

singleQuotes 单引号

true

Boolean

Whether single quotes can be used as replacement for double quotes. This is convenient when you need to work with strings inside strings.
是否可以使用单引号替代双引号。当你需要在字符串内部使用字符串时,这是很方便的。

resultType 结果类型

String

Sets the class of the result type (type from output).
设置结果类型的类(来自输出的类型)。

trim 修剪

true

Boolean

Whether to trim the value to remove leading and trailing whitespaces and line breaks.
是否要修剪值以去除前导和尾随的空格和换行符。

Variables 变量

The Java language allows the following variables to be used in the script:
Java 语言允许在脚本中使用以下变量:

Variable 变量 Java Type Java 类型 Description 描述

context 背景

Context

The CamelContext CamelContext

exchange 交换

Exchange

The Camel Exchange 骆驼交易所

message 消息

Message

The Camel message 骆驼消息

body 身体

Object

The message body 消息正文

Functions 功能

The Java language allows the following functions to be used in the script:
Java 语言允许在脚本中使用以下功能:

Function 功能 Description 描述

bodyAs(type)

To convert the body to the given type.
将身体转换为给定的类型。

headerAs(name, type) headerAs(名称,类型)

To convert the header with the name to the given type.
将带有名称的标题转换为给定类型。

headerAs(name, defaultValue, type)
headerAs(名称,默认值,类型)

To convert the header with the name to the given type. If no header exists, then use the given default value.
将具有给定类型的标题转换为名称。如果没有标题存在,则使用给定的默认值。

exchangePropertyAs(name, type)
交换属性为(name, type)

To convert the exchange property with the name to the given type.
将具有指定名称的交换属性转换为给定类型。

exchangePropertyAs(name, defaultValue, type)
exchangePropertyAs(名称,默认值,类型)

To convert the exchange property with the name to the given type. If no exchange property exists, then use the given default value.
将具有指定名称的交换属性转换为给定的类型。如果不存在交换属性,则使用给定的默认值。

optionalBodyAs(type) 可选的 BodyAs(type)

To convert the body to the given type, returned wrapped in java.util.Optional.
将身体转换为给定的类型,返回包装在 java.util.Optional 中。

optionalHeaderAs(name, type)
可选头部作为(名称,类型)

To convert the header with the name to the given type, returned wrapped in java.util.Optional.
将带有名称的标题转换为给定类型,返回包装在 java.util.Optional 中。

optionalExchangePropertyAs(name, type)
可选的交换属性作为(名称,类型)

To convert the exchange property with the name to the given type, returned wrapped in java.util.Optional.
将具有指定名称的交换属性转换为给定类型,并返回用 java.util.Optional 包装的结果。

These functions are convenient for getting the message body, header or exchange properties as a specific Java type.
这些函数方便地将消息体、头部或交换属性作为特定的 Java 类型获取。

Here we want to get the message body as a com.foo.MyUser type we can do as follows:
在这里,我们想要将消息正文作为 com.foo.MyUser 类型获取,可以按照以下方式进行操作:

var user = bodyAs(com.foo.MyUser.class);

You can omit .class to make the function a little smaller:
您可以省略 .class 以使函数变得更小:

var user = bodyAs(com.foo.MyUser);

The type must be a fully qualified class type, but that can be inconvenient to type all the time. In such a situation, you can configure an import in the camel-joor.properties file as shown below:
类型必须是一个完全限定的类类型,但是每次都输入完整的类名可能会不方便。在这种情况下,您可以在 camel-joor.properties 文件中配置一个导入,如下所示:

import com.foo.MyUser;

And then the function can be shortened:
然后这个函数可以被简化:

var user = bodyAs(MyUser);

Dependency Injection 依赖注入

The Camel Java language allows dependency injection by referring to beans by their id from the Camel registry. For optimization purposes, then the beans are injected once in the constructor and the scopes are singleton. This requires the injected beans to be thread safe as they will be reused for all processing.
Camel Java 语言允许通过从 Camel 注册表中引用 bean 的 id 来进行依赖注入。为了优化目的,这些 bean 在构造函数中只被注入一次,并且作用域是单例的。这要求被注入的 bean 在所有处理过程中都是线程安全的,因为它们将被重复使用。

In the Java code you declare the injected beans using the syntax #bean:beanId.
在 Java 代码中,您可以使用 #bean:beanId 语法声明注入的 bean。

For example, suppose we have the following bean
例如,假设我们有以下的 bean

public class MyEchoBean {

    public String echo(String str) {
        return str + str;
    }

    public String greet() {
        return "Hello ";
    }
}

And this bean is registered with the name myEcho in the Camel registry.
这个 bean 在 Camel 注册表中以名称 myEcho 注册。

The Java code can then inject this bean directly in the script where the bean is in use:
Java 代码可以直接在使用该 bean 的脚本中注入该 bean

from("direct:start")
    .transform().java("'Hello ' + #bean:myEcho.echo(bodyAs(String))")
    .to("mock:result");

Now this code may seem a bit magic, but what happens is that the myEcho bean is injected via a constructor, and then called directly in the script, so it is as fast as possible.
现在这段代码可能看起来有点神奇,但实际上的情况是 myEcho bean 通过构造函数注入,然后在脚本中直接调用,所以速度尽可能快。

Under the hood, Camel Java generates the following source code compiled once:
在底层,Camel Java 生成以下源代码,只编译一次:

public class JoorScript1 implements org.apache.camel.language.joor.JoorMethod {

    private MyEchoBean myEcho;

    public JoorScript1(CamelContext context) throws Exception {
        myEcho = context.getRegistry().lookupByNameAndType("myEcho", MyEchoBean.class);
    }

    @Override
    public Object evaluate(CamelContext context, Exchange exchange, Message message, Object body, Optional optionalBody) throws Exception {
        return "Hello " + myEcho.echo(bodyAs(exchange, String.class));
    }
}

You can also store a reference to the bean in a variable which would more resemble how you would code in Java
您还可以将对 bean 的引用存储在一个变量中,这样更接近您在 Java 中编写代码的方式

from("direct:start")
    .transform().java("var bean = #bean:myEcho; return 'Hello ' + bean.echo(bodyAs(String))")
    .to("mock:result");

Notice how we declare the bean as if it is a local variable via var bean = #bean:myEcho. When doing this we must use a different name as myEcho is the variable used by the dependency injection. Therefore, we use bean as name in the script.
注意我们如何通过 var bean = #bean:myEcho 将 bean 声明为局部变量。在这样做时,我们必须使用不同的名称,因为 myEcho 是依赖注入使用的变量。因此,在脚本中我们使用 bean 作为名称。

Auto imports 汽车进口

The Java language will automatically import from: 

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
import org.apache.camel.*;
import org.apache.camel.util.*;

Configuration file 配置文件

You can configure the jOOR language in the camel-joor.properties file which by default is loaded from the root classpath. You can specify a different location with the configResource option on the Java language.
您可以在默认情况下从根类路径加载的 camel-joor.properties 文件中配置 jOOR 语言。您可以使用 Java 语言的 configResource 选项指定不同的位置。

For example, you can add additional imports in the camel-joor.properties file by adding:
例如,您可以通过添加以下内容在 camel-joor.properties 文件中添加额外的导入:

import com.foo.MyUser;
import com.bar.*;
import static com.foo.MyHelper.*;

You can also add aliases (key=value) where an alias will be used as a shorthand replacement in the code.
您还可以添加别名( key=value ),其中别名将在代码中用作简写替代。

echo()=bodyAs(String) + bodyAs(String)

Which allows using echo() in the jOOR language script such as:
允许在 jOOR 语言脚本中使用 echo()

from("direct:hello")
    .transform(java("'Hello ' + echo()"))
    .log("You said ${body}");

The echo() alias will be replaced with its value resulting in a script as:
echo() 别名将被替换为其值,生成的脚本如下:

.transform(java("'Hello ' + bodyAs(String) + bodyAs(String)"))

You can configure a custom configuration location for the camel-joor.properties file or reference to a bean in the registry:
您可以为 camel-joor.properties 文件配置自定义配置位置,或者引用注册表中的 bean

JavaLanguage joor = (JavaLanguage) context.resolveLanguage("java");
java.setConfigResource("ref:MyJoorConfig");

And then register a bean in the registry with id MyJoorConfig that is a String value with the content.
然后在注册表中注册一个 id 为 MyJoorConfig 的 bean,它是一个包含内容的字符串值。

String config = "....";
camelContext.getRegistry().put("MyJoorConfig", config);

Example 例子

For example, to transform the message using jOOR language to the upper case
例如,使用 jOOR 语言将消息转换为大写

from("seda:orders")
  .transform().java("message.getBody(String.class).toUpperCase()")
  .to("seda:upper");

And in XML DSL:
在 XML DSL 中:

<route>
   <from uri="seda:orders"/>
   <transform>
     <java>message.getBody(String.class).toUpperCase()</joor>
   </transform>
   <to uri="seda:upper"/>
</route>

Multi statements 多语句

It is possible to include multiple statements. The code below shows an example where the user header is retrieved in a first statement. And then, in a second statement we return a value whether the user is null or not.
可以包含多个语句。下面的代码示例中,第一个语句中检索到 user 头部。然后,在第二个语句中,我们返回一个值,判断用户是否 null

from("seda:orders")
  .transform().java("var user = message.getHeader(\"user\"); return user != null ? \"User: \" + user : \"No user exists\";")
  .to("seda:user");

Notice how we have to quote strings in strings, and that is annoying, so instead we can use single quotes:
注意我们在字符串中需要引用字符串,这很烦人,所以我们可以使用单引号代替

from("seda:orders")
  .transform().java("var user = message.getHeader('user'); return user != null ? 'User: ' + user : 'No user exists';")
  .to("seda:user");

Hot re-load 热重新加载

You can turn off pre-compilation for the Java language and then Camel will recompile the script for each message. You can externalize the code into a resource file, which will be reloaded on each message as shown:
您可以关闭 Java 语言的预编译,然后 Camel 将为每个消息重新编译脚本。您可以将代码外部化到资源文件中,每个消息都会重新加载,如下所示:

JavaLanguage java = (JavaLanguage) context.resolveLanguage("java");
java.setPreCompile(false);

from("jms:incoming")
    .transform().java("resource:file:src/main/resources/orders.java")
    .to("jms:orders");

Here the Java code is externalized into the file src/main/resources/orders.java which allows you to edit this source file while running the Camel application and try the changes with hot-reloading.
这里的 Java 代码被外部化到文件 src/main/resources/orders.java 中,这样你可以在运行 Camel 应用程序时编辑这个源文件,并尝试使用热加载进行更改。

In XML DSL it’s easier because you can turn off pre-compilation in the <java> XML element:
在 XML DSL 中更容易,因为你可以在 <java> XML 元素中关闭预编译

<route>
    <from uri="jms:incoming"/>
    <transform>
      <java preCompile="false">resource:file:src/main/resources/orders.java</java>
    </transform>
    <to uri="jms:orders"/>
</route>

Lambda-based AggregationStrategy
基于 Lambda 的聚合策略

The Java language has special support for defining an org.apache.camel.AggregationStrategy as a lambda expression. This is useful when using EIP patterns that use aggregation such as the Aggregator, Splitter, Recipient List, Enrich, and others.
Java 语言对于将 org.apache.camel.AggregationStrategy 定义为 lambda 表达式有特殊支持。在使用使用聚合等 EIP 模式(如聚合器、分割器、收件人列表、增强等)时,这非常有用。

To use this, then the Java language script must be in the following syntax:
要使用这个,那么 Java 语言脚本必须采用以下语法:

(e1, e2) -> { }

Where e1 and e2 are the old Exchange and new Exchange from the aggregate method in the AggregationStrategy. The returned value is used as the aggregated message body, or use null to skip this.
其中 e1e2AggregationStrategy 方法中的旧交换和新交换。返回的值用作聚合消息的主体,或者使用 null 跳过此步骤。

The lambda syntax is representing a Java util BiFunction<Exchange, Exchange, Object> type.
lambda 语法表示一个 Java util 类型。

For example, to aggregate message bodies together, we can do this as shown:
例如,要将消息正文聚合在一起,我们可以按如下所示进行操作:

(e1, e2) -> {
  String b1 = e1.getMessage().getBody(String.class);
  String b2 = e2.getMessage().getBody(String.class);
  return b1 + ',' + b2;
}

Limitations 限制

The Java Camel language is only supported as a block of Java code that gets compiled into a Java class with a single method. The code that you can write is therefore limited to a number of Java statements.
Java 骆驼语言仅支持作为一块 Java 代码块,编译成一个具有单个方法的 Java 类。因此,您可以编写的代码受到一些 Java 语句的限制。

The supported runtime is intended for Java standalone, Spring Boot, Camel Quarkus and other microservices runtimes. It is not supported in OSGi, Camel Karaf or any kind of Java Application Server runtime.
支持的运行时适用于 Java 独立运行、Spring Boot、Camel Quarkus 和其他微服务运行时。它不支持 OSGi、Camel Karaf 或任何类型的 Java 应用服务器运行时。

Java does not support runtime compilation with Spring Boot using fat jar packaging (https://github.com/jOOQ/jOOR/issues/69), it works with exploded classpath.
Java 在使用 Spring Boot 进行 fat jar 打包时不支持运行时编译(https://github.com/jOOQ/jOOR/issues/69),但在使用爆炸式类路径时可以正常工作。

Dependencies 依赖

To use scripting languages in your camel routes, you need to add a dependency on camel-joor. 

If you use Maven you could add the following to your pom.xml, substituting the version number for the latest and greatest release. 

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-joor</artifactId>
  <version>x.x.x</version>
</dependency>

Spring Boot Auto-Configuration
Spring Boot 自动配置

When using java with Spring Boot make sure to use the following Maven dependency to have support for auto configuration:
使用 Spring Boot 时,请确保使用以下 Maven 依赖项以获得自动配置支持:

<dependency>
  <groupId>org.apache.camel.springboot</groupId>
  <artifactId>camel-joor-starter</artifactId>
  <version>x.x.x</version>
  <!-- use the same version as your Camel core version -->
</dependency>

The component supports 8 options, which are listed below.
该组件支持 8 个选项,如下所示。

Name 姓名 Description 描述 Default 默认 Type 类型

camel.language.java.enabled
启用 Java 语言

Whether to enable auto configuration of the java language. This is enabled by default.
是否启用 Java 语言的自动配置。默认情况下启用。

Boolean 布尔值

camel.language.java.pre-compile
骆驼语言的 Java 预编译

Whether the expression should be pre compiled once during initialization phase. If this is turned off, then the expression is reloaded and compiled on each evaluation.
表达式是否应在初始化阶段预先编译一次。如果关闭此选项,则在每次评估时重新加载和编译表达式。

true 真实的

Boolean 布尔值

camel.language.java.single-quotes

Whether single quotes can be used as replacement for double quotes. This is convenient when you need to work with strings inside strings.
是否可以使用单引号替代双引号。当你需要在字符串内部使用字符串时,这是很方便的。

true 真实的

Boolean 布尔值

camel.language.java.trim 驼峰语言 Java 修剪

Whether to trim the value to remove leading and trailing whitespaces and line breaks.
是否要修剪值以去除前导和尾随的空格和换行符。

true 真实的

Boolean 布尔值

camel.language.joor.enabled
骆驼语言.joor.启用

Whether to enable auto configuration of the joor language. This is enabled by default.
是否启用 joor 语言的自动配置。默认情况下启用。

Boolean 布尔值

camel.language.joor.pre-compile
骆驼语言.joor.预编译

Whether the expression should be pre compiled once during initialization phase. If this is turned off, then the expression is reloaded and compiled on each evaluation.
是否应在初始化阶段预编译表达式。如果关闭此选项,则在每次评估时重新加载和编译表达式。

true 真实的

Boolean 布尔值

camel.language.joor.single-quotes
camel.language.joor.single-quotes 翻译为简体中文为:camel.language.joor.single-quotes

Whether single quotes can be used as replacement for double quotes. This is convenient when you need to work with strings inside strings.
是否可以使用单引号替代双引号。当你需要在字符串内部使用字符串时,这是很方便的。

true 真实的

Boolean 布尔值

camel.language.joor.trim 骆驼语言.joor.trim

Whether to trim the value to remove leading and trailing whitespaces and line breaks.
是否要修剪值以去除前导和尾随的空格和换行符。

true 真实的

Boolean 布尔值