如何正确解析 Java 中的 SES 退回 JSON SNS 通知
How correctly parse SES bounced JSON SNS Notification in Java
我从 SNS 主题收到 JSON,我认为这是不正确的
{
"Type":"Notification",
"MessageId":"message-id-is-this",
"TopicArn":"bouncer.topic.name.here",
"Message":"{\"notificationType\":\"Bounce\",\"bounce\":{\"bounceType\":\"Permanent\",\"bounceSubType\":\"General\",\"bouncedRecipients\":[{\"emailAddress\":\"bounce@simulator.amazonses.com\",\"action\":\"failed\",\"status\":\"5.1.1\",\"diagnosticCode\":\"smtp; 550 5.1.1 user unknown\"}],\"timestamp\":\"2017-04-24T12:58:05.716Z\",\"feedbackId\":\"feedback.id.is.here\",\"remoteMtaIp\":\"192.168.10.1\",\"reportingMTA\":\"dsn; smtp.link.here\"},\"mail\":{\"timestamp\":\"2017-04-24T12:58:05.000Z\",\"source\":\"senderEmail@domainname.com\",\"sourceArn\":\"arn:aws:ses:us-east-1:someid:identity/some@domain.org\",\"sourceIp\":\"127.0.0.1\",\"sendingAccountId\":\"sending.account.id.is.this\",\"messageId\":\"message-id-is-this\",\"destination\":[\"bounce@simulator.amazonses.com\"]}}",
"Timestamp":"2017-04-24T12:58:05.757Z",
"SignatureVersion":"1",
"Signature":"signature.link",
"SigningCertURL":"certificate.link.here",
"UnsubscribeURL":"un.subscribe.link"
}
问题出在 "Message" 属性上,它不是持有对象,而是指对象的字符串
包含
"Message":"{\"key\":\"value\"}"
而不是
"Message":{"key":"value"}"
因此未映射到消息 class
我暂时通过接收到字符串变量然后转换它来解决这个问题
private String Message;
private Message objMessage;
然后
Notification noti = toObject(jsonString, Notification.class);
Message msg = toObject(noti.getMessage(), Message.class);
noti.setObjMessage(msg);
为了转换,我正在使用 ObjectMapper.readValue(...)
解决这个问题的正确方法是什么?
此格式正确。
循环中有两个独立的服务,SES和SNS。
外部结构是 SNS 通知 -- SNS 使用的通用结构确实可以传递 SNS 传递的任何内容。
它包含一个 Message
属性,其值为 总是 一个字符串,因为这是 SNS 传递的消息类型 -- 字符串。不是对象。 SNS 无法感知 Message
属性的值是任何类型的对象。它可以是任何东西,只要它是有效的 UTF-8,SNS 不在乎。
要将对象作为字符串传递,必须对其进行序列化...而内部序列化恰好也是 JSON。
所以Message
嵌套在JSON-in-JSON.
这就是它应该的样子。
当外部对象被序列化时,内部的保留JSON字符必须被转义,如下所示。在第一次反序列化之后,您就得到了 SES 发送给您的内容——一个 JSON 字符串。
然后您需要反序列化生成的字符串以获取您的对象。
我不认为你做错了。如果你是,那么我多年来一直做错了。
我从 SNS 主题收到 JSON,我认为这是不正确的
{
"Type":"Notification",
"MessageId":"message-id-is-this",
"TopicArn":"bouncer.topic.name.here",
"Message":"{\"notificationType\":\"Bounce\",\"bounce\":{\"bounceType\":\"Permanent\",\"bounceSubType\":\"General\",\"bouncedRecipients\":[{\"emailAddress\":\"bounce@simulator.amazonses.com\",\"action\":\"failed\",\"status\":\"5.1.1\",\"diagnosticCode\":\"smtp; 550 5.1.1 user unknown\"}],\"timestamp\":\"2017-04-24T12:58:05.716Z\",\"feedbackId\":\"feedback.id.is.here\",\"remoteMtaIp\":\"192.168.10.1\",\"reportingMTA\":\"dsn; smtp.link.here\"},\"mail\":{\"timestamp\":\"2017-04-24T12:58:05.000Z\",\"source\":\"senderEmail@domainname.com\",\"sourceArn\":\"arn:aws:ses:us-east-1:someid:identity/some@domain.org\",\"sourceIp\":\"127.0.0.1\",\"sendingAccountId\":\"sending.account.id.is.this\",\"messageId\":\"message-id-is-this\",\"destination\":[\"bounce@simulator.amazonses.com\"]}}",
"Timestamp":"2017-04-24T12:58:05.757Z",
"SignatureVersion":"1",
"Signature":"signature.link",
"SigningCertURL":"certificate.link.here",
"UnsubscribeURL":"un.subscribe.link"
}
问题出在 "Message" 属性上,它不是持有对象,而是指对象的字符串
包含
"Message":"{\"key\":\"value\"}"
而不是
"Message":{"key":"value"}"
因此未映射到消息 class
我暂时通过接收到字符串变量然后转换它来解决这个问题
private String Message;
private Message objMessage;
然后
Notification noti = toObject(jsonString, Notification.class);
Message msg = toObject(noti.getMessage(), Message.class);
noti.setObjMessage(msg);
为了转换,我正在使用 ObjectMapper.readValue(...)
解决这个问题的正确方法是什么?
此格式正确。
循环中有两个独立的服务,SES和SNS。
外部结构是 SNS 通知 -- SNS 使用的通用结构确实可以传递 SNS 传递的任何内容。
它包含一个 Message
属性,其值为 总是 一个字符串,因为这是 SNS 传递的消息类型 -- 字符串。不是对象。 SNS 无法感知 Message
属性的值是任何类型的对象。它可以是任何东西,只要它是有效的 UTF-8,SNS 不在乎。
要将对象作为字符串传递,必须对其进行序列化...而内部序列化恰好也是 JSON。
所以Message
嵌套在JSON-in-JSON.
这就是它应该的样子。
当外部对象被序列化时,内部的保留JSON字符必须被转义,如下所示。在第一次反序列化之后,您就得到了 SES 发送给您的内容——一个 JSON 字符串。
然后您需要反序列化生成的字符串以获取您的对象。
我不认为你做错了。如果你是,那么我多年来一直做错了。