2

I am receiving JSON from SNS topic, which I believe is not correct

{
   "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"
}

The problem is with "Message" attribute which instead of holding an object, is referring to string of an object

contains

"Message":"{\"key\":\"value\"}"

instead of

"Message":{"key":"value"}"

hence not mapped to Message class

Temporarily I solved this problem by receiving into string variable and then convert it

private String Message;
private Message objMessage;

and then

Notification noti = toObject(jsonString, Notification.class);
Message msg = toObject(noti.getMessage(), Message.class);
noti.setObjMessage(msg);

for transformation, I am using ObjectMapper.readValue(...)

What is the correct way to solve this problem?

PHP Avenger
  • 1,744
  • 6
  • 37
  • 66
  • Hi could you please share the source code for this....I couldn't parse SNS notification message into Message object...your help should be really needful. – VelNaga Feb 14 '19 at 04:06

1 Answers1

7

This format is correct.

There are two independent services in the loop, SES and SNS.

The outer structure is an SNS notification -- a generic structure that SNS uses do deliver anything that SNS delivers.

It contains a Message attribute, whose value is always a string, since that is what kind of messages SNS delivers -- strings. Not objects. SNS has no sense of the Message attribute's value being any kind of object. It could be anything, as long as it's valid UTF-8, SNS doesn't care.

To deliver an object as a string, it has to be serialized... and the inner serialization happens to also be JSON.

So Message is nested JSON-in-JSON.

And that's what it's supposed to look like.

When the outer object is serialized, the reserved JSON characters inside must be escaped, as shown here. After the first deserialization, you have exactly what SES sent you -- a JSON string.

You then need to deserialize the resulting string in order to get your object.

I don't think you're doing it wrong. If you are, then I've been doing it wrong for years.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427