Java 中的 AWS Lambda 函数处理程序 - AWS Lambda

Java 中的 AWS Lambda 函数处理程序

您的 Lambda 函数的处理程序是函数代码中处理事件的方法。当调用函数时,Lambda 运行处理程序方法。当处理程序退出或返回响应时,它可用于处理另一个事件。

在以下示例中,名为 Handler 的类定义名为 handleRequest 的处理程序方法。处理程序方法接受一个事件和上下文对象作为输入并返回一个字符串。

Handler.java

package example; import com.amazonaws.services.lambda.runtime.Context import com.amazonaws.services.lambda.runtime.RequestHandler import com.amazonaws.services.lambda.runtime.LambdaLogger ... // Handler value: example.Handler public class Handler implements RequestHandler<Map<String,String>, String>{ Gson gson = new GsonBuilder().setPrettyPrinting().create(); @Override public String handleRequest(Map<String,String> event, Context context) { LambdaLogger logger = context.getLogger(); String response = new String("200 OK"); // log execution details logger.log("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv())); logger.log("CONTEXT: " + gson.toJson(context)); // process event logger.log("EVENT: " + gson.toJson(event)); logger.log("EVENT TYPE: " + event.getClass().toString()); return response; } }

Lambda 运行时将以 JSON 格式的字符串接收事件,并将其转换为对象。它将事件对象以及提供有关调用和函数详细信息的上下文对象传递给函数处理程序。您通过在函数的配置上设置处理程序参数来告诉运行时要调用哪个方法。

处理程序格式

  • package.Class::method – 完整格式。例如:example.Handler::handleRequest

  • package.Class – 实现处理程序接口的函数的缩写格式。例如:example.Handler

您可以在处理程序方法外部添加初始化代码 ,以便跨多个调用重用资源。当运行时加载处理程序时,它会运行静态代码和类构造函数。在初始化期间创建的资源在调用之间保留在内存中,处理程序可以重复使用这些资源数千次。

在以下示例中,当函数提供其第一个事件时,会创建记录器、序列化程序和 AWS 开发工具包客户端。由同一函数实例提供的后续事件要快得多,因为这些资源已经存在。

Handler.java – 初始化代码

// Handler value: example.Handler public class Handler implements RequestHandler<SQSEvent, String>{ private static final Logger logger = LoggerFactory.getLogger(Handler.class); private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private static final LambdaAsyncClient lambdaClient = LambdaAsyncClient.create(); ... @Override public String handleRequest(SQSEvent event, Context context) { String response = new String(); // call Lambda API logger.info("Getting account settings"); CompletableFuture<GetAccountSettingsResponse> accountSettings = lambdaClient.getAccountSettings(GetAccountSettingsRequest.builder().build()); // log execution details logger.info("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv())); ...

本指南的 GitHub 存储库提供了易于部署的示例应用程序,用于演示各种处理程序类型。有关详细信息,请参阅本主题的末尾

选择输入和输出类型

您可以在处理程序方法的签名中指定事件映射到的对象类型。在上述示例中,Java 运行时将事件反序列化为实现 Map<String,String> 接口的类型。字符串到字符串映射适用于平面事件,如下所示:

Event.json – 天气数据

{ "temperatureK": 281, "windKmh": -3, "humidityPct": 0.55, "pressureHPa": 1020 }

但是,每个字段的值必须是字符串或数字。如果事件包含具有对象作为值的字段,则运行时无法对该字段进行反序列化并返回错误。

选择与函数处理的事件数据一起使用的输入类型。您可以使用基本类型、泛型类型或明确定义的类型。

输入类型

  • IntegerLongDouble 等– 事件是一个没有其他格式的数字 — 例如,3.5。运行时将值转换为指定类型的对象。

  • String – 事件是 JSON 字符串,包括引号 — 例如,"My string."。运行时将值(不带引号)转换为 String 对象。

  • TypeMap<String,Type> 等– 事件是一个 JSON 对象。运行时将其反序列化为指定类型或接口的对象。

  • List<Integer>List<String>List<Object> 等– 事件是一个 JSON 数组。运行时将其反序列化为指定类型或接口的对象。

  • InputStream – 事件是任何 JSON 类型。运行时将文档的字节流传递给处理程序而不进行修改。您可以对输入进行反序列化并将输出写到输出流。

  • 库类型 – 对于 AWS 服务发送的事件,请使用 aws-lambda-java-events 库中的类型。

如果您定义了自己的输入类型,它应该是可反序列化的、可变的普通旧 Java 对象 (POJO),对事件中的每个字段具有默认的构造函数和属性。事件中未映射到属性的键以及未包含在事件中的属性将被删除而不显示错误。

输出类型可以是对象或 void。运行时将返回值序列化为文本。如果输出是具有字段的对象,运行时将其序列化为 JSON 文档。如果它是包装原始值的类型,则运行时返回该值的文本表示形式。

处理程序接口

aws-lambda-java-core 库为处理程序方法定义了两个接口。使用提供的接口简化处理程序配置,并在编译时验证处理程序方法签名。

RequestHandler 接口是一个泛型类型,它采用两个参数:输入类型和输出类型。这两种类型都必须是对象。使用此接口时,Java 运行时会将事件反序列化为具有输入类型的对象,并将输出序列化为文本。当内置序列化与输入和输出类型配合使用时,请使用此接口。

Handler.java – 处理程序接口

// Handler value: example.Handler public class Handler implements RequestHandler<Map<String,String>, String>{ @Override public String handleRequest(Map<String,String> event, Context context)

要使用您自己的序列化,请实现 RequestStreamHandler 接口。使用此接口,Lambda 将向您的处理程序传递输入流和输出流。处理程序从输入流读取字节,写到输出流,并返回 void。

以下示例使用缓冲读取器和写入器类型来处理输入和输出流。它使用 Gson 库进行序列化和反序列化。

HandlerStream.java

import com.amazonaws.services.lambda.runtime.Context import com.amazonaws.services.lambda.runtime.RequestStreamHandler import com.amazonaws.services.lambda.runtime.LambdaLogger ... // Handler value: example.HandlerStream public class HandlerStream implements RequestStreamHandler { Gson gson = new GsonBuilder().setPrettyPrinting().create(); @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { LambdaLogger logger = context.getLogger(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("US-ASCII"))); PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, Charset.forName("US-ASCII")))); try { HashMap event = gson.fromJson(reader, HashMap.class); logger.log("STREAM TYPE: " + inputStream.getClass().toString()); logger.log("EVENT TYPE: " + event.getClass().toString()); writer.write(gson.toJson(event)); if (writer.checkError()) { logger.log("WARNING: Writer encountered an error."); } } catch (IllegalStateException | JsonSyntaxException exception) { logger.log(exception.toString()); } finally { reader.close(); writer.close(); } } }

示例处理程序代码

本指南的 GitHub 存储库包括演示如何使用各种处理程序类型和接口的示例应用程序。每个示例应用程序都包含用于轻松部署和清理的脚本、一个 AWS SAM 模板和支持资源。

Java 中的示例 Lambda 应用程序

  • blank-java – 一个 Java 函数,用于显示 Lambda 的 Java 库、日志记录、环境变量、层、AWS X-Ray 跟踪、单元测试和 AWS 开发工具包的使用情况。

  • java-basic – 具有单元测试和可变日志记录配置的最小 Java 函数。

  • java-events – 一个最小的 Java 函数,它将 aws-lambda-java-events 库与不需要 AWS 开发工具包作为依赖项的事件类型(例如 Amazon API Gateway)结合使用。

  • java-events-v1sdk – 一个 Java 函数,它将 aws-lambda-java-events 库与需要 AWS 开发工具包作为依赖项的事件类型(Amazon Simple Storage Service、Amazon DynamoDB 和 Amazon Kinesis)结合使用。

  • s3-java – 一个 Java 函数,它处理来自 Amazon S3 的通知事件,并使用 Java 类库 (JCL) 从上传的图像文件创建缩略图。

blank-javas3-java 应用程序将 AWS 服务事件作为输入并返回字符串。java-basic 应用程序包括几种类型的处理程序:

要测试不同的处理程序类型,只需更改 AWS SAM 模板中的处理程序值即可。有关详细说明,请参阅示例应用程序的自述文件。