I'm coding a functionality of handling callbacks from Amazon Simple Email Service via SNS HTTP requests. I would like to parse message provided by Amazon to local object structure. Problem is that SNS is wrapping JSON message into String and it could not be parsed by Jackson. I'm getting an error:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `xxx.email.domain.aws.ses.Notification` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"notificationType":"Delivery","mail":{"timestamp":"2019-10-02T14:43:14.570Z" ... next values of the message ... }}')
Entire message from SNS looks like this one:
{
"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"
}
My actual local structure looks like this:
@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;
}
I'm looking for some way to tell Jackson that Message
should be extracted from a String and treated as a normal JSON.
Edit
deserialization
private MessageWrapper deserializeMessage(String message) throws IOException {
return new ObjectMapper().readValue(message, MessageWrapper.class);
}