AWS Lambda json 带有 jackson 注释的反序列化

AWS Lambda json deserialization with jackson annotations

我正在调用具有 json 正文的 aws lambda。所以 json 的字段与 POJO 中的字段名称不同。所以我所做的是在字段上添加@JsonProperty 来告诉杰克逊 json 中的名称是什么。但出于某种原因,它似乎无法识别它们并且所有字段均为空。如果我传递一个 json 与它正在工作的 POJO 具有相同的字段名称。这是我的 class:

public class Event implements Identifiable {

    @JsonProperty("distinct_id")
    private String distinctId;

    @JsonProperty("user_id")
    private Integer userId;

    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    private LocalDateTime eventDateTime;

    //Here are the getters and setters
}

如果我通过了

{"distinct_id":"123", "user_id":123, "dt":"2017-01-04T08:45:04+00:00"} 

所有字段都为空,并且使用 distinctId、userId、eventDateTime 序列化正常,但它也无法识别我的自定义 serializers/deserializers 但这实际上是同一个问题。

我的结论是,出于某种原因,aws jackson 没有使用注释,但它没有意义。

为属性创建 getter 方法并将 @JsonProperty 放在 getter 方法上。

听起来注释类型和数据绑定 (ObjectMapper) 之间的版本不匹配:两者必须是相同的主要版本。具体来说,Jackson 1.x 注释与 Jackson 1.x 数据绑定一起工作; 2.x 和 2.x.

通过 Java 包可见差异:Jackson 1.x 使用 org.codehaus.jackson,而 Jackson 2.x 使用 com.fasterxml.jackson。确保为您使用的 ObjectMapper 导入正确的注释。

所以我找到了一种方法来做到这一点。您需要实施 RequestStreamHandler,它为您提供可以使用的输入和输出流:

import com.amazonaws.services.lambda.runtime.RequestStreamHandler

public class ChartHandler implements RequestStreamHandler {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        DeserializationClass deserializedInput = objectMapper.readValue(inputStream, DeserializationClass.class)
        objectMapper.writeValue(outputStream, deserializedInput); //write to the outputStream what you want to return
    }

}

有了输入和输出流,您就可以独立于用于解析它的格式和框架。

看看 AWS 文档中的这段引述:

You shouldn't rely on any other features of serialization frameworks such as annotations. If you need to customize the serialization behavior, you can use the raw byte stream to use your own serialization.

发件人:https://docs.aws.amazon.com/lambda/latest/dg/java-programming-model-req-resp.html

我遇到了同样的问题,需要 MyCustomClass 正确地进出 Lambda Function,以便它可以通过我的 State MachineStep Function 没有任何问题。

根据 发布的内容,我得到了一个适合我的解决方案,我将其发布,希望它能帮助像我一样被困的其他人:

import java.io.InputStream;
import java.io.OutputStream;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class StaticSearchPagingLambdaFunctionHandler implements RequestStreamHandler {

    LambdaLogger logger = null;
    MyCustomClass myCustomClass = null;

    // Register the JavaTimeModule for LocalDate conversion
    ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) {    

            myCustomClass = objectMapper.readValue(inputStream, MyCustomClass .class);

            // ...
            // Do stuff with myCustomClass
            // ...

            objectMapper.writeValue(outputStream, myCustomClass);
    }
}

即使 JSON 字符串与 ObjectMapper 写入 OutPutStream 的打印方式不同,当下一个 lambda 函数在通过 [=17= 时接收它时], 它仍然会正确转换为 LocalDate

确保在 MyCustomClass 中您的 toString() 方法打印正确。我的 toString() 方法如下所示:

import java.time.LocalDate;

import org.json.JSONObject;

public class SimpleSearch {

    private LocalDate startDate;
    private LocalDate endDate;

    // ...
    // Getters and Setters for the LocalDate variables
    // ...

    @Override
    public String toString() {
        return new JSONObject(this).toString();
    }

    public SimpleSearch() {}
}

然后你的 JSON 打印输出在发送到 lambda 时将始终看起来像这样,而不是其他疯狂的 Jackson 格式:

{
    "startDate": "2018-11-01",
    "endDate": "2018-11-16"
}

我使用的一些 Maven 依赖项:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20180813</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.7</version>
</dependency>

希望 AWS 将 Jackson 转换为相互的 JSON 转换,这样我们就不必再求助于这些自定义转换了。