本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
什么是 JavaCallout?
Apigee 提供了一系列政策,以满足安全性、数据转换、流量管理等常见 API 管理要求。
但在某些情况下,您的 API 需要标准政策中未实现的自定义行为。在这些情况下,Apigee 提供了多种选项,使您能够编写脚本或代码来自定义 API 行为。一种方法是使用 Java 实现所需的行为。
支持的 Java 版本包括:Oracle JDK 11 和 OpenJDK 11。
如何在代理中使用 Java 代码?
通过 JavaCallout 政策,您可以在执行代理流内调用 Java 代码。您的 Java 代码需要实现某些特定于 Apigee 的 Java 接口,以使代码能够与执行代理交互。例如,存在用于获取和设置标头、查询参数、流变量以及代理当前流上下文中的其他实体的 Java 方法。
何时应使用 JavaCallout?
我们来了解一下 JavaCallout 非常有用以及您应该考虑使用其他方法的情况。
首先考虑替代方法
在使用 JavaCallout 之前,请注意,也可以改用备用方法。例如:
- 对于轻量级操作(例如对远程服务的 HTTP API 调用),请考虑使用 ServiceCallout 政策。请参阅服务标注政策。
- 如需对消息内容进行相对简单的交互(例如修改或提取 HTTP 标头、参数或消息内容),可以使用 JavaScript 或 PythonScript 政策。
可以在 Java 代码中执行的操作
JavaCallout 支持以下基本操作:
- 检查或处理请求或响应消息
- 获取和设置流变量。您可以使用 Java 方法访问 Apigee 流变量。如果您想要访问键值对映射 (KVM) 信息,请使用 KVM 政策,将 KVM 值分配给流变量,然后就可以从 Java Callout 中访问流变量了。
- 调用外部服务
- 引发错误
- 处理错误消息和状态代码
无法在 Java 代码中执行的操作
大多数系统调用都是不允许的。无法执行以下操作:
- 进行内部文件系统读取或写入。这意味着您无法使用任何 Java 包来读入内部文件系统;但是,您可以执行外部远程调用。
- 获取机器上当前进程、进程列表或 CPU/内存利用率的信息。
- 访问
expressions-1.0.0.jar
和message-flow-1.0.0.jar
中的源代码。
虽然此类调用可能会正常工作,但不受支持,并且可能随时会被主动停用。不要在您的代码中进行此类调用。
请勿使用或依赖 Apigee 随附的 Java 库。这些库仅适用于 Apigee 产品功能,并且不能保证各个版本之都可以使用该库。如果您使用此类库,请仅在非生产的演示中使用它们。
Hello Java callout
我们来看一个基本的 hello world Java callout 示例。在本示例中,我们通过一个返回“hello world”响应的 Java callout 创建一个简单的代理。该代理可能会返回两个可能的响应之一:
- 如果您传入“username”标头以及“name”值,则代理会返回以下内容:
Hello, <name>!
- 如果省略标头,则代理只返回:
"Hello, Guest!"
下载入门级项目
为简单起见,我们在 GitHub 上的 Apigee api-platform-samples 代码库中准备了一个基本项目。
- 将 api-platform-samples 下载或克隆到您的系统中。 如果您的系统上已经有
api-platform-samples
,请执行pull
以确保您拥有最新版本。 - 在您选择的终端或代码编辑器中,转到
api-platform-samples/doc-samples/java-hello
项目。
编写 Java 代码
- 打开 Java 源文件:
java-hello/callout/src/main/java/HelloJava.java
。此文件是我们将实现的主 Java 类的框架版本。Apigee Java Callout 代码需要用到导入的包。这些类提供了可让您访问代理执行上下文的方法。我们稍后会介绍编译和部署此代码的步骤。
package com.apigeesample; import com.apigee.flow.execution.ExecutionContext; import com.apigee.flow.execution.ExecutionResult; import com.apigee.flow.execution.spi.Execution; import com.apigee.flow.message.MessageContext; public class HelloJava implements Execution { public ExecutionResult execute(MessageContext messageContext, ExecutionContext executionContext) { try { // Your code here. return ExecutionResult.SUCCESS; } catch (Exception e) { return ExecutionResult.ABORT; } } }
- 将注释掉的行
// Your code here
替换为以下代码:
String name = messageContext.getMessage().getHeader("username"); if (name != null && name.length()>0) { messageContext.getMessage().setContent("Hello, " + name + "!"); messageContext.getMessage().removeHeader("username"); } else { messageContext.getMessage().setContent("Hello, Guest!"); }
- 保存文件。
使用 Maven 编译代码
- 确保已安装 Maven:
mvn -version
- 使用以下方法之一在本地 Maven 代码库中安装所需的 JAR 依赖项:
- 将以下代码段添加到
pom.xml
文件中,以从 Artifact Registry 下载所需的 JAR 依赖项:<repositories> <repository> <id>artifact-registry</id> <url>https://us-maven.pkg.dev/apigee-release/apigee-java-callout-dependencies</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.apigee.gateway.libraries</groupId> <artifactId>message-flow</artifactId> <version>1.0.0</version> <scope>compile</scope> <type>jar</type> </dependency> <dependency> <groupId>com.apigee.infra.libraries</groupId> <artifactId>expressions</artifactId> <version>1.0.0</version> <scope>compile</scope> <type>jar</type> </dependency> </dependencies>
- 使用以下
curl
调用从 Artifact Registry 下载所需的 JAR 依赖项:curl "https://us-maven.pkg.dev/apigee-release/apigee-java-callout-dependencies/com/apigee/gateway/libraries/message-flow/1.0.0/message-flow-1.0.0.jar" -v -L -o message-flow-1.0-0.jar
curl "https://us-maven.pkg.dev/apigee-release/apigee-java-callout-dependencies/com/apigee/infra/libraries/expressions/1.0.0/expressions-1.0.0.jar" -v -L -o expressions-1.0.0.jar
- 执行脚本
java-hello/buildsetup.sh
。此脚本会从 Apigee GitHub 代码库下载所需的 JAR 依赖项。
- 将以下代码段添加到
- 使用 cd 命令转到
java-hello/callout
目录。 - 执行 Maven:
mvn clean package
- 如果需要,请验证 JAR 文件
edge-custom-policy-java-hello.jar
是否已复制到java-hello/apiproxy/resources/java
。要使用代理部署的 JAR 文件必须存放在该位置。
部署和调用代理
请按照以下步骤部署和测试 API 代理:
- 切换到
java-hello
目录: - 压缩 API 代理软件包:
zip apiproxy-bundle.zip -r apiproxy -x \*.\*~
- 部署代理最简单的方法是将它打包为 ZIP 文件,并将代理软件包上传到您的 Apigee 组织的环境中。请参阅创建 API 代理。请务必使用上传代理软件包选项。另请参阅 Apigee 社区中的上传代理软件包中的 API 代理的提示和技巧。
- 部署代理后,请尝试对其进行调用:
curl https://$HOSTNAME/java-hello -H "username:Will"
此操作会返回“Hello, Will!
关于代理
让我们快速检查此代理中使用的政策。注意代理在代理流中的放置位置及原因。
“分配消息”政策
“分配消息”政策附加到 ProxyEndpoint 请求流。它从请求中复制 username 标头,并将其分配给响应。此操作允许附加到响应流的 Java Callout 政策访问 username 标头,并使用该标头的值构建自定义响应正文。
<AssignMessage async="false" continueOnError="false" enabled="true" name="CopyHeader"> <DisplayName>CopyHeader</DisplayName> <Copy source="request"> <Headers> <Header name="username"/> </Headers> </Copy> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="response"/> </AssignMessage>
Java callout 政策
Java callout 政策附加到响应流中。这是因为自定义 Java 代码会更改响应标头和消息。政策的 ClassName 元素指定了由政策执行的主类。ResourceURL 元素是您构建的 JAR 文件的名称,并添加到代理的 resources/java
目录中。
<JavaCallout name="hello-java"> <ClassName>com.apigeesample.HelloJava</ClassName> <ResourceURL>java://edge-custom-policy-java-hello.jar</ResourceURL> </JavaCallout>
关于 Java callout 的须知事项
有关实现 Java callout 的重要注意事项:
- 从
com.apigee.flow.execution
和com.apigee.flow.message
包中导入类。这些包必须包含在打包和部署的 JAR 文件中。您可以通过管理界面代理编辑器上传 Java JAR,也可以在本地开发的 API 代理中将其包含在/resources/java
目录中。 - 实现 Execution 接口。在 API 代理中执行的任何 Java 代码都必须实现 Execution。
- Java Callout 政策不包含实际代码。相反,Java Callout 政策引用 Java“资源”(您必须将该资源打包在一个 JAR 中)。
- 应避免的软件包名称:请勿在 Java Callout 中使用 io.apigee 或 io.apigee。这些名称由其他 Apigee 模块预留和使用。
- 如果您的 Java 标注依赖于打包为独立 JAR 文件的其他第三方库,则将这些 JAR 文件也放在
/resources/java
目录中,以确保在运行时正确加载它们。 - 如果有多个 JAR,只需将它们添加为其他资源。您无需修改政策配置来引用其他 JAR 文件。将其放入
/resources/java
即可。 - 如需详细了解如何上传 Java JAR,请参阅资源文件。