gpt4 book ai didi

java - Jackson反序列化SNS消息报错MismatchedInputException

转载 作者:搜寻专家 更新时间:2023-11-01 02:35:09 26 4
gpt4 key购买 nike

我正在编写一项功能,通过 SNS HTTP 请求处理来自 Amazon Simple Email Service 的回调。我想将亚马逊提供的消息解析为本地对象结构。问题是 SNS 将 JSON 消息包装成字符串,而 Jackson 无法解析它。我收到一个错误:

com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造 `xxx.email.domain.aws.ses.Notification` 的实例(尽管至少存在一个 Creator):没有字符串参数构造函数/从字符串值反序列化的工厂方法 ('{"notificationType":"Delivery","mail":{"timestamp":"2019-10-02T14:43:14.570Z"... 消息的下一个值 ... }}')

来自 SNS 的整个消息如下所示:

 {
"Type" : "Notification",
"MessageId" : "4944xxxx-711d-57d4-91b8-8215cxxxxx",
"TopicArn" : "arn:aws:sns:eu-west-1:...",
"Message" : "{\"notificationType\":\"Delivery\",\"mail\":{\"timestamp\":\"2019-10-02T14:43:14.570Z\", ... next values of the message ... },\"delivery\":{\"timestamp\":\"2019-10-02T14:43:16.030Z\", ... next values of the message ... }}",
"Timestamp" : "2019-10-02T14:43:16.062Z",
"SignatureVersion" : "1",
"Signature" : "signature base64",
"SigningCertURL" : "cert url",
"UnsubscribeURL" : "unsubscribe url"
}

我的实际本地结构如下所示:

@Data
@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class MessageWrapper {
private String type;
private String messageId;
private String topicArn;
private Notification message;
private Date timestamp;
private String signatureVersion;
private String signature;
private String signingCertURL;
private String unsubscribeURL;
}

@Data
public class Notification {
private String notificationType;
private Mail mail;
}

@Data
public class Mail {
private String messageId;
private String source;
private String sourceArn;
private String sourceIp;
private String sendingAccountId;
private String[] destination;
}

我正在寻找某种方式来告诉 Jackson Message 应该从字符串中提取并作为普通 JSON 处理。

编辑

反序列化

private MessageWrapper deserializeMessage(String message) throws IOException {
return new ObjectMapper().readValue(message, MessageWrapper.class);
}

最佳答案

我认为要解决这个问题,您需要为 MessageWrapper 类中的 Notification 字段和 Mail 字段自定义反序列化器在 Notification 类中,如下所示:

public class NotificationDeserializer extends JsonDeserializer<Notification> {
@Override
public Notification deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String text = p.getText();

return new ObjectMapper().readValue(text, Notification.class);
}
}

public class MailDeserializer extends JsonDeserializer<Mail> {
@Override
public Mail deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String text = p.getText();

return new ObjectMapper().readValue(text, Mail.class);
}
}

在你的类上添加一些注释,如下所示:

@Data
@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class MessageWrapper {
private String type;
private String messageId;
private String topicArn;
@JsonDeserialize(using = NotificationDeserializer.class)
private Notification message;
private Date timestamp;
private String signatureVersion;
private String signature;
private String signingCertURL;
private String unsubscribeURL;
}

@Data
public class Notification {
private String notificationType;
@JsonDeserialize(using = MailDeserializer.class)
private Mail mail;
}

@Data
public class Mail {
private String messageId;
private String source;
private String sourceArn;
private String sourceIp;
private String sendingAccountId;
private String[] destination;
}

编辑 1

MailDeserializer 实际上并不需要。 NotificationDeserializer 单独处理这个问题。

编辑 2

必须在自定义反序列化器中使用新的 ObjectMapper

关于java - Jackson反序列化SNS消息报错MismatchedInputException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58204267/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com