我将 Spring Boot (2.26) 与适用于 Java 的 AWS 开发工具包 (1.11.761) 结合使用。
我的问题是 @LambdaFunction 无法反序列化到我的 POJO,失败原因为:
"com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of
com.example.Sentence
(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"end": 16, "id": 1, "start": 0, "text": "Hello, Foobar!!!", "type": "SENTENCE", "uuid": "de0134a93c1f4f2dbd910ae39438359d", "warnings": []}') at [Source: (byte[])""{\"end\": 16, \"id\": 1, \"start\": 0, \"text\": \"Hello, Foobar!!!\", \"type\": \"SENTENCE\", \"uuid\": \"de0134a93c1f4f2dbd910ae39438359d\", \"warnings\": []}""; line: 1, column: 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,它只会将转义的 byte[] 交给 Jackson,而 Jackson 会失败。
我可以在 Jackson 或 SDK 上进行任何配置来防止这种情况吗?我已经尝试将 Jackson 从 AWS SDK 的 Maven 依赖项中排除,以防版本冲突,但得到了相同的结果。
最佳答案
您需要一种方法让 Jackson 构建您的 Sentence 对象。有两种方法可以实现此目的:
- 添加一个空的构造函数以及 getter 和 setter 方法,也许您需要在每个字段(uuid 除外)上使用
@JsonProperty("fieldName")
- 添加一个带有
@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;
}
在我看来,第二种方法更好,以便使用不可变对象(immutable对象)
关于java - AWS @LambdaFunction 无法反序列化为 POJO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61170798/