本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
内容
让您可使用 Java 实施 Apigee 政策未开箱包括的自定义行为。在 Java 代码中,您可以访问代理流中的消息属性(标头、查询参数、内容)和流变量。如果您刚开始使用此政策,请参阅如何创建 Java 标注。
支持的 Java 版本包括:Oracle JDK 11 和 OpenJDK 11
此政策是一项可扩展政策,使用此政策可能会影响费用或使用情况,具体取决于您的 Apigee 许可。如需了解政策类型和使用情况影响,请参阅政策类型。
何时使用
如需了解准则,请参阅如何创建 Java callout 中的“我应在何时使用 JavaCallout?”。
简介
通过 JavaCallout 政策,您可以获取和设置流变量、执行自定义逻辑并执行错误处理、从请求或响应中提取数据,等等。该政策让您可实施任何其他标准 Apigee 政策未涵盖的自定义行为。
您可以使用所需的任何软件包 JAR 文件打包 Java 应用。请注意,您可以使用 JavaCallout 执行的操作存在一些限制。下文的限制部分中列出了这些限制。示例
简单示例
如何创建 JavaCallout在 Java 代码中检索属性
通过此政策的 <Property> 元素,您可以指定可在 Java 代码中在运行时检索的名称/值对。如需查看使用属性的有效示例,请参阅如何在 JavaCallout 政策中使用属性。
使用 <Property> 元素的 name 特性指定可用于从 Java 代码访问属性的名称。<Property> 元素的值(起始标记和结束标记之间的值)是 Java 代码将接收的值。值必须是字符串;您无法引用流变量来获取值。
- 配置属性。在这里,属性值为变量名称
response.status.code。<JavaCallout async="false" continueOnError="false" enabled="true" name="JavaCallout"> <DisplayName>JavaCallout</DisplayName> <ClassName>com.example.mypolicy.MyJavaCallout</ClassName> <ResourceURL>java://MyJavaCallout.jar</ResourceURL> <Properties> <Property name="source">response.status.code</Property> </Properties> </Javascript>
- 在 Java 代码中,在 Execution 类实施上实施以下构造函数,如下所示:
public class MyJavaCallout implements Execution{ public MyJavaCallout(Map<string, string> props){ // Extract property values from map. } ... }
在 Java 代码中设置流变量
如需清楚了解如何在 Java 代码的消息上下文(流变量)中设置变量,请参阅这篇 Apigee 社区博文。
元素参考
元素参考描述了 JavaCallout 政策的元素和特性。
<JavaCallout name="MyJavaCalloutPolicy"> <ClassName>com.example.mypolicy.MyJavaCallout</ClassName> <ResourceURL>java://MyJavaCallout.jar</ResourceURL> </JavaCallout>
<JavaCallout> 特性
<JavaCallout name="MyJavaCalloutPolicy" enabled="true" continueOnError="false" async="false" >
下表介绍了所有政策父元素通用的特性:
| 属性 | 说明 | 默认值 | 状态 |
|---|---|---|---|
name |
政策的内部名称。 (可选)使用 |
不适用 | 需要 |
continueOnError |
设置为 设置为 |
false | 可选 |
enabled |
设置为 设为 |
true | 可选 |
async |
此特性已弃用。 |
false | 已弃用 |
<DisplayName> 元素
除了用于 name 特性之外,还可以用于在管理界面代理编辑器中给政策添加不同的自然语言名称标签。
<DisplayName>Policy Display Name</DisplayName>
| 默认值 |
不适用 如果省略此元素,则会使用政策的 |
|---|---|
| 状态 | 可选 |
| 类型 | 字符串 |
<ClassName> 元素
指定在 JavaCallout 政策运行时执行的 Java 类的名称。该类必须包含在 <ResourceURL> 指定的 JAR 文件中。另请参阅如何创建 Java 标注。
<JavaCallout name="MyJavaCalloutPolicy"> <ResourceURL>java://MyJavaCallout.jar</ResourceURL> <ClassName>com.example.mypolicy.MyJavaCallout</ClassName> </JavaCallout>
| 默认: | 不适用 |
| 状态: | 需要 |
| 类型: | 字符串 |
<Properties> 元素
添加您可以在运行时从 Java 代码访问的新属性。
<Properties> <Property name="propName">propertyValue</Property> </Properties>
| 默认: | 无 |
| 状态: | 可选 |
| 类型: | 字符串 |
<Property> 元素
指定可在运行时从 Java 代码访问的属性。您必须为每个属性指定一个字面量字符串值;您无法在此元素中引用流变量。如需查看使用属性的有效示例,请参阅如何在 JavaCallout 政策中使用属性。
<Properties> <Property name="propName">propertyValue</Property> </Properties>
| 默认: | 无 |
| 状态: | 可选 |
| 类型: | 字符串 |
属性
| 属性 | 说明 | 默认值 | 状态 |
|---|---|---|---|
| name |
指定属性的名称。 |
不适用 | 必填。 |
<ResourceURL> 元素
此元素指定将在 JavaCallout 政策运行时执行的 Java JAR 文件。
您可以在 API 代理范围(API 代理软件包的 /apiproxy/resources/java 下方或 API 代理编辑器导航工具窗格的“脚本”部分中)或组织或环境范围中存储此文件,以便在多个 API 代理中重复使用,如资源文件中所述。
<JavaCallout name="MyJavaCalloutPolicy"> <ResourceURL>java://MyJavaCallout.jar</ResourceURL> <ClassName>com.example.mypolicy.MyJavaCallout</ClassName> </JavaCallout>
| 默认: | 无 |
| 状态: | 需要 |
| 类型: | 字符串 |
错误参考信息
This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.
Runtime errors
These errors can occur when the policy executes.
| Fault code | HTTP status | Cause | Fix |
|---|---|---|---|
steps.javacallout.ExecutionError |
500 |
Occurs when Java code throws an exception or returns null during the execution of a JavaCallout policy. |
build |
Deployment errors
These errors can occur when the proxy containing the policy is deployed.
| Error name | Fault string | HTTP status | Occurs when |
|---|---|---|---|
ResourceDoesNotExist |
Resource with name
[name] and type [type] does not exist |
N/A | The file specified in the <ResourceURL> element does not exist. |
JavaCalloutInstantiationFailed |
Failed to instantiate the JavaCallout Class [classname] |
N/A | The class file specified in the <ClassName> element is not in the
jar. |
IncompatibleJavaVersion |
Failed to load java class [classname] definition due to - [reason] |
N/A | See fault string. Supported Java versions include: Oracle JDK 7/8 and OpenJDK 7/8 |
JavaClassNotFoundInJavaResource |
Failed to find the ClassName in java resource [jar_name] -
[class_name] |
N/A | See fault string. |
JavaClassDefinitionNotFound |
Failed to load java class [class_name] definition due to - [reason] |
N/A | See fault string. |
NoAppropriateConstructor |
No appropriate constructor found in JavaCallout class [class_name] |
N/A | See fault string. |
NoResourceForURL |
Could not locate a resource with URL [string] |
N/A | See fault string. |
Fault variables
These variables are set when this policy triggers an error. For more information, see What you need to know about policy errors.
| Variables | Where | Example |
|---|---|---|
fault.name="fault_name" |
fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. | fault.name Matches "ExecutionError" |
javacallout.policy_name.failed |
policy_name is the user-specified name of the policy that threw the fault. | javacallout.JC-GetUserData.failed = true |
Example error response
{ "fault":{ "faultstring":"Failed to execute JavaCallout. [policy_name]", "detail":{ "errorcode":"javacallout.ExecutionError" } } }
Example fault rule
<FaultRule name="JavaCalloutFailed"> <Step> <Name>AM-JavaCalloutError</Name> </Step> <Condition>(fault.name Matches "ExecutionError") </Condition> </FaultRule>
架构
编译和部署
如需详细了解如何编译自定义 Java 代码并使用代理进行部署,请参阅如何创建 Java 标注。
限制
下面是编写 Java callout 代码时需要考虑的限制:
- 大多数系统调用都是不允许的。例如,您无法进行内部文件系统读取或写入。
- 通过套接字访问网络。Apigee 会限制对 sitelocal、anylocal、loopback 和 linklocal 地址的访问。
- 标注无法获取有关计算机上的当前进程、进程列表或 CPU/内存利用率的信息。尽管有些此类调用可能正常工作,但不受支持,并且可能随时会被主动停用。为了实现前向兼容性,您应该避免在代码中进行此类调用。
- 不支持依赖于 Apigee 未随附的 Java 库。这些库仅适用于 Apigee 产品功能,并且不能保证各个版本之都可以使用该库。
- 请勿在 Java 标注中使用
io.apigee或com.apigee作为软件包名称。这些名称由其他 Apigee 模块保留和使用。
打包
将 JAR 放在 /resources/java 下的 API 代理中。如果您的 JavaCallout 依赖于打包为独立 JAR 文件的其他第三方库,则将这些 JAR 文件也放在 /resources/java 目录中,以确保在运行时正确加载它们。
如果您使用管理界面创建或修改代理,请添加新资源并指定其他依赖的 JAR 文件。如果有多个 JAR,只需将它们添加为其他资源。您无需修改政策配置来引用其他 JAR 文件。将其放入 /resources/java 即可。
如需了解如何上传 Java JAR,请参阅资源文件。
如需查看详细示例,了解如何使用 Maven 或 javac 打包和部署 JavaCallout 政策,请参阅如何创建 Java callout。
Javadoc
GitHub 上此处提供了用于编写 JavaCallout 代码的 Javadoc。您需要克隆 HTML 或将其下载到您的系统,然后在浏览器中打开 index.html 文件。
使用说明和最佳做法
- 使用多个 JavaCallout 政策时,请考虑将常见的 JAR 作为环境范围的资源上传。部署到同一环境时,相比将相同的 JAR 与多个代理软件包一起打包的做法相比,这种做法更高效。
- 避免将同一 JAR 文件的多个副本或版本打包并部署到一个环境。例如,Apigee 建议您避免以下情形:
- 将同一 JAR 作为代理软件包的一部分以及部署为环境资源。
- 将 JAR 文件的一个版本部署为环境资源,将另一个版本部署为代理捆绑包的一部分。
由于潜在的 ClassLoader 冲突,部署相同 JAR 的多个副本可能会在运行时导致不确定的行为。
- JavaCallout 政策不包含实际代码。相反,该政策会引用 Java“资源”,并在执行 Java 代码的 API 流中定义步骤。您可以通过管理界面代理编辑器上传 Java JAR,也可以在本地开发的 API 代理中将其包含在
/resources/java目录中。 - 对于轻量级操作(例如对远程服务的 API 调用),我们建议使用 ServiceCallout 政策。请参阅服务标注政策。
- 对于与消息内容的相对简单互动(例如修改或提取 HTTP 标头、参数或消息内容),Apigee 建议使用 JavaScript 政策。