

# 自定义 Lambda Java 函数的序列化
<a name="java-custom-serialization"></a>

Lambda [Java 托管式运行时](lambda-java.md#java-runtimes)支持 JSON 事件的自定义序列化。自定义序列化可以简化代码并有可能提高性能。

**Topics**
+ [何时使用自定义序列化](#custom-serialization-use-cases)
+ [实现自定义序列化](#implement-custom-serialization)
+ [测试自定义序列化](#test-custom-serialization)

## 何时使用自定义序列化
<a name="custom-serialization-use-cases"></a>

调用 Lambda 函数时，需要将输入事件数据反序列化为 Java 对象，并且需要将函数的输出序列化回可以作为函数响应返回的格式。Lambda Java 托管式运行时提供默认的序列化和反序列化功能，非常适合处理来自各种 AWS 服务的事件有效载荷，例如 Amazon API Gateway 和 Amazon Simple Queue Service（Amazon SQS）。要在函数中使用这些服务集成事件，请向项目中添加 [aws-java-lambda-events](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-events) 依赖项。此 AWS 库包含表示这些服务集成事件的 Java 对象。

您也可以使用自己的对象来表示传递给 Lambda 函数的事件 JSON。托管式运行时会尝试将 JSON 序列化为对象的新实例，且该新实例具有其默认行为。如果默认序列化器无用例所需的行为，请使用自定义序列化。

例如，假设函数处理程序需要 `Vehicle` 类作为输入，并且此类具有以下结构：

```
public class Vehicle {
    private String vehicleType;
    private long vehicleId;
}
```

但是，JSON 事件有效载荷如下所示：

```
{
    "vehicle-type": "car",
    "vehicleID": 123
}
```

在这种情况下，托管式运行时中的默认序列化需要 JSON 属性名称与驼峰式大小写的 Java 类属性名称（`vehicleType`、`vehicleId`）相匹配。JSON 事件中的属性名称并非为驼峰式大小写（`vehicle-type`、`vehicleID`），因此必须使用自定义序列化。

## 实现自定义序列化
<a name="implement-custom-serialization"></a>

使用[服务提供程序接口](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html)加载您选择的序列化器，而非托管式运行时的默认序列化逻辑。您可以使用标准 `RequestHandler` 接口将 JSON 事件有效载荷直接序列化为 Java 对象。

**要在 Lambda Java 函数中使用自定义序列化**

1. 添加 [aws-lambda-java-core](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-core)（作为依赖项）。此库包括 [CustomPojoSerializer](https://github.com/aws/aws-lambda-java-libs/blob/main/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/CustomPojoSerializer.java) 接口，以及其他用于在 Lambda 中使用 Java 的接口定义。

1. 在项目的 `src/main/resources/META-INF/services/` 目录中创建名为 `com.amazonaws.services.lambda.runtime.CustomPojoSerializer` 的文件。

1. 在此文件中，指定自定义序列化器实现（该实现必须实现 `CustomPojoSerializer` 接口）的完全限定名称。示例：

   ```
   com.mycompany.vehicles.CustomLambdaSerialzer
   ```

1. 实现 `CustomPojoSerializer` 接口以提供自定义序列化逻辑。

1. 在 Lambda 函数中使用标准 `RequestHandler` 接口。托管式运行时将使用自定义序列化程序。

有关如何使用 fastJson、Gson、Moshi 和 jackson-jr 等常用库实现自定义序列化的更多示例，请参阅《AWS GitHub repository》中的 [custom-serialization](https://github.com/aws/aws-lambda-java-libs/tree/main/samples/custom-serialization) 示例。

## 测试自定义序列化
<a name="test-custom-serialization"></a>

测试函数，确保序列化和反序列化逻辑按预期运行。您可以使用 AWS Serverless Application Model 命令行接口（AWS SAMCLI）来模拟 Lambda 有效载荷的调用。在引入自定义序列化器时，此举可以帮助您快速测试和迭代函数。

1. 使用要调用函数的 JSON 事件有效载荷创建文件，然后调用 AWS SAM CLI。

1. 运行 [sam local invoke](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html ) 命令，在本地调用函数。示例：

   ```
   sam local invoke -e src/test/resources/event.json
   ```

有关更多信息，请参阅 [Locally invoke Lambda functions with AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-invoke.html)。