我将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依赖项中排除,以防版本冲突,但结果相同。
答案 0 :(得分:0)
您需要让Jackson构造Sentence对象的方法。有两种方法可以实现此目的:
@JsonProperty("fieldName")
(除了uuid)@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;
}
我更喜欢第二种方法,以便使用不可变对象