Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda json deserialization with jackson annotations

I'm calling an aws lambda with a json body. So the fields of the json are with different name from the ones in the POJO. So what I did is to add @JsonProperty on the fields to tell jackson what are the names in json. But for some reason it seems that it doesn't recognize them and all the fields are null. If I pass a json with the same field names as the POJO it's working. Here's my 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
}

If I pass

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

all the fields are null and with distinctId, userId, eventDateTime it's serializing ok with the exception that it also doesn't recognize my custom serializers/deserializers but this actually is the same problem.

My conclusion is that for some reason the aws jackson is not working with the annotations but it doesn't make sense.

like image 391
Hristo Angelov Avatar asked Jan 05 '17 08:01

Hristo Angelov


People also ask

What are @deserialization annotations in Jackson?

Deserialization annotations are used when we deserialize JSON string into an Object. Jackson library provides several deserialization annotations such as @JsonCreator, @JacksonInject, @JsonAnySetter, etc. These annotations are mostly used in setter Let's understand each one of them one by one with an example.

How do I deserialize JSON in Jackson?

The Jackson deserialization annotations are: @JsonSetter. The @JsonSetter annotation tells Jackson to deserialize the JSON into Java object using the name given in the setter method. Use this annotation when your JSON property names are different to the fields of the Java object class, and you want to map them.

How do I use system text jsonserializer with system Lambda?

Lambda functions using System.Text.Json must declare LambdaSystemTextJsonSerializer as their JSON serializer using the JsonSerializer assembly attribute. Microsoft has published an excellent migration guide for switching from Newtonsoft.Json to System.Text.Json.

What is @jsonsetter annotation in Jackson?

The @JsonSetter annotation tells Jackson to deserialize the JSON into Java object using the name given in the setter method. Use this annotation when your JSON property names are different to the fields of the Java object class, and you want to map them. A Java class that uses the @JsonSetter annotation is:


2 Answers

So I found a way to do this. You need to implement RequestStreamHandler which gives you input and output streams which you can work with:

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
    }

}

Having the input and output streams makes you independent of the format and frameworks you use to parse it.

like image 112
Hristo Angelov Avatar answered Oct 22 '22 07:10

Hristo Angelov


Take a look at this quote from AWS documentation:

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.

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

like image 9
jccampos Avatar answered Oct 22 '22 06:10

jccampos