AWS @LambdaFunction无法反序列化为POJO

时间:2020-04-12 11:36:43

标签: java aws-lambda jackson

我将Spring Boot(2.26)与适用于Java的AWS开发工具包(1.11.761)结合使用。

我的问题是@LambdaFunction无法反序列化到我的POJO,失败:

“ com.fasterxml.jackson.databind.exc.MismatchedInputException:无法 构造com.example.Sentence的实例(尽管至少有一个 创建者存在):没有任何字符串参数构造函数/工厂方法 从字符串值反序列化('{“ end”:16,“ id”:1,“ start”:0, “ text”:“ Hello,Foobar !!!”,“ type”:“ SENTENCE”,“ uuid”: [来源:“ de0134a93c1f4f2dbd910ae39438359d”,“警告”:[]}') (byte [])“” {\“ end \”:16,\“ id \”:1,\“开始\”:0,\“文本\”:\“你好, Foobar !!! \“,\” type \“:\” SENTENCE \“,\” uuid \“: \“ de0134a93c1f4f2dbd910ae39438359d \”,\“警告\”:[]}“”;行:1 栏:1]

public interface TemplateLambda {
    @LambdaFunction(functionName="....")
    Sentence getSentence(TemplateInput input);

    @LambdaFunction(functionName="....")
    String getString(TemplateInput input);
}

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Sentence {

    @JsonIgnore
    private UUID uuid = UUID.randomUUID();

    private Long id;
    private String text;
    private String type;
    private List<Warning> warnings = new ArrayList<>();
    private Long start;
    private Long end;
}

调用者:

final ObjectMapper objectMapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

final TemplateLambda lambda = LambdaInvokerFactory.builder()
            .lambdaClient(AWSLambdaClientBuilder.defaultClient())
            .objectMapper(objectMapper)
            .build(TemplateLambda.class);

TemplateInput input = new TemplateInput("Foobar");
try {
    String s = lambda.getString(input);
    Sentence sent = objectMapper.readValue(s, Sentence.class); // SUCCEEDS
    logger.info("THIS SUCCEEDS);

    Sentence output = lambda.getSentence(input); // FAILS
    logger.info("THIS FAILS");

} catch (Exception e) {
    e.printStackTrace();
}

我还验证了跳过@LambdaFunction批注并手动调用会以byte []格式给出转义的JSON字符串,即'\“ {\” id \“:\ 123} \”'。如果我不手动取消转义并删除前导和尾随引号,则会遇到相同的失败。

看来,如果我要求String作为返回类型,SDK将处理转义,但如果我要求POJO,它将转义的字节[]交给杰克逊和杰克逊失败。

我可以在Jackson或SDK上进行任何配置来防止这种情况吗?我已经尝试过将杰克逊从AWS SDk的Maven依赖项中排除,以防版本冲突,但结果相同。

1 个答案:

答案 0 :(得分:0)

您需要让Jackson构造Sentence对象的方法。有两种方法可以实现此目的:

  1. 添加一个空的构造函数以及getter和setter方法,也许您需要在每个字段上使用@JsonProperty("fieldName")(除了uuid)
  2. 添加带有@JsonCreator的构造函数,并为构造函数的每个参数添加@JsonProperty("filedName"),我也会添加getter方法
@JsonCreator
public Sentence(@JsonProperty("id")Long id,
     @JsonProperty("text")String text,
     @JsonProperty("type") String type,
     @JsonProperty("warnings") List<Warning> warnings,
     @JsonProperty("start") Long start,
     @JsonProperty("end") Long end) {
    this.id = id;
    this.text = text;
    this.type = type;
    this.warnings = new ArrayList<>();
    this.start = start;
    this.end = end;
}

我更喜欢第二种方法,以便使用不可变对象