简体   繁体   English

Java AWS Lambda 处理程序 - 深度嵌套的 Json

[英]Java AWS Lambda Handler - Deeply Nested Json

I have a deeply nested json object I want to send to an Java AWS Lambda.我有一个深度嵌套的 json 对象,我想发送到 Java AWS Lambda。

I've tried different types for the request handler.我为请求处理程序尝试了不同的类型。

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

In all cases the following simple, single-level, json will work fine:在所有情况下,以下简单的单级 json 都可以正常工作:

{
  "hello": "world"
}

But any nested properties fails:但是任何嵌套的属性都失败了:

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

With the error:随着错误:

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)

How can I write an AWS Java Lambda that allows for deeply nested json properties?如何编写允许深度嵌套 json 属性的 AWS Java Lambda?

Option 1:选项1:
Change event type to Map<String, Object> and use Gson to convert to your data model.event类型更改为Map<String, Object>并使用 Gson 转换为您的数据模型。

Example:例子:

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 "";
    }
}

Option 2:选项 2:
For complex json/data models, you can use RequestStreamHandler class which doesn't require you to provide a data type.对于复杂的 json/data 模型,您可以使用RequestStreamHandler类,它不需要您提供数据类型。 It will give you InputStream which you can convert to any data model you like.它将为您提供InputStream ,您可以将其转换为您喜欢的任何数据模型。

Example:例子:

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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM