【问题标题】:Java AWS Lambda Handler - Deeply Nested JsonJava AWS Lambda 处理程序 - 深度嵌套的 Json
【发布时间】:2021-09-14 14:14:46
【问题描述】:

我有一个深度嵌套的 json 对象,我想发送到 Java AWS Lambda。

我尝试了不同类型的请求处理程序。

public class LambdaHandler implements RequestHandler<Map<String, ?>, String>
public class LambdaHandler implements RequestHandler<JsonNode, String>
public class LambdaHandler implements RequestHandler<String, String>

在所有情况下,以下简单的单级 json 都可以正常工作:

{
  "hello": "world"
}

但是任何嵌套属性都会失败:

{
  "hello": "world",
  "oh": {
      "no": "it's dead"
  }
}

出现错误:

An error occurred during JSON parsing: java.lang.RuntimeException
java.lang.RuntimeException: An error occurred during JSON parsing
Caused by: java.io.UncheckedIOException: com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
 at [Source: (ByteArrayInputStream); line: 3, column: 9] (through reference chain: java.util.LinkedHashMap["oh"])
    at com.amazonaws.services.lambda.runtime.serialization.factories.JacksonFactory$InternalSerializer.fromJson(JacksonFactory.java:184)
Caused by: com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
 at [Source: (ByteArrayInputStream); line: 3, column: 9] (through reference chain: java.util.LinkedHashMap["oh"])
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1442)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1216)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1126)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:63)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:10)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1719)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1228)
    at com.amazonaws.services.lambda.runtime.serialization.factories.JacksonFactory$InternalSerializer.fromJson(JacksonFactory.java:182)

如何编写允许深度嵌套 json 属性的 AWS Java Lambda?

【问题讨论】:

  • 你试过RequestHandler&lt;Map&lt;String, JsonNode&gt;, String&gt;吗?我不确定String 文字是否会自动反序列化为TextNodeJsonNode 的后代),但尝试一下也无妨
  • RequestHandler&lt;Map&lt;String, JsonNode&gt;, String&gt;TextNode 都有同样的问题。有没有我可以利用的方法来提供自定义 serde?那只是RequestStreamHandler吗?
  • @JacobG。啊,你知道我什至没有正确测试这个。我正在尝试通过 docker 进行测试,只是假设每次都在重建图像。我一直在通过所有这些变化来测试旧图像。将得到修复并再次测试。

标签: java amazon-web-services aws-lambda


【解决方案1】:

选项 1:
event 类型更改为 Map&lt;String, Object&gt; 并使用 Gson 转换为您的数据模型。

例子:

public class Handler implements RequestHandler<Map<String, Object>, String> {

    @Override
    public String handleRequest(Map<String, Object> event, Context context) {
        Gson gson = new Gson();
        MyDataModel request = gson.fromJson(gson.toJson(event), MyDataModel.class);

        // use request

        return "";
    }
}

选项 2:
对于复杂的 json/data 模型,您可以使用 RequestStreamHandler 类,它不需要您提供数据类型。它将为您提供InputStream,您可以将其转换为您喜欢的任何数据模型。

例子:

public class HandlerStream implements RequestStreamHandler {

    @Override
    public void handleRequest(InputStream input, OutputStream output, Context context) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        JsonElement eventElement = new JsonParser().parse(reader);
        JsonObject event = (JsonObject) eventElement;
        
        MyDataModel request = new Gson().fromJson(event, MyDataModel.class);
        
        // use request
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    相关资源
    最近更新 更多