Reputation: 442
I have been trying to parse this string to get the value of the Target-key
{
"Type" : "Notification",
"MessageId" : "something",
"Message" : "{\"buildId\":\"something\",\"somekey\":\"somevalue\",\"startTimeMillis\":1592526605121,\"table\":{\"key1\":\"val1\",\"tableName\":\"some table\",\"tableprop\":{\"bucketCount\":123,\"bucketColumns\":[\"X\",\"Y\"]},\"tableSortProperty\":{\"sortColumns\":[\"X\",\"Y\"]}},\"createStatementLocation\":{\"s3Bucket\":\"somebucket\",\"s3Prefix\":\"someprefix\"},\"Target-key\":\"Target-Value\"}",
"Timestamp" : "2020-06-19T19:23:46.378Z"
}
I have tried the following approach:
message.getBody() returns the Json String. Here message is the SQS Message object
Approach 1:
JSONObject jsonObject = new JSONObject(message.getBody());
JSONObject obj = (JSONObject) jsonObject.get("Message");
String res = (String)obj.get("Target-key");
I am getting the error at line 2 of above code
java.lang.String cannot be cast to org.json.JSONObject: java.lang.ClassCastException
java.lang.ClassCastException: java.lang.String cannot be cast to org.json.JSONObject
Approach 2: Using Jackson also produces class cast exception on line2 again.
Map<String,Map<String,String> > mymap;
mymap = objectMapper.readValue(message.getBody(), Map.class);
Map<String, String> mymap2 = mymap.get("Message");
String res = mymap2.get("Target-key");
Approach 3: Also Tried using Jackson Tree Node
However, the below solution do seem to work but I want to know why the above approach is failing
Map<String,String> messageMap;
messageMap = objectMapper.readValue(message.getBody(), Map.class);
Map<String,String> mmap = objectMapper.readValue(messageMap.get("Message"), Map.class);
String res = mmap.get("Target-key");
PS:I have tried many alternatives and similar question on stack overflow but it is not helping my case.
The actual key and value have been replaced with some-key and some-value.
EDIT: I sneaked into the source data and updated JSON
Upvotes: 0
Views: 2892
Reputation: 5289
Now that we can see the original source your problem is obvious. The value of Message is a string instead of a nested object.
JSONObject jsonObject = new JSONObject(message.getBody());
JSONObject obj= new JSONObject(jsonObject.getString("Message"));
Upvotes: 2
Reputation: 365
There is a parsing error in your json at "bucketCount": XYZ,
XYZ myst be inside inverted commas like "XYZ". You can check your json at http://json2table.com
Upvotes: 0
Reputation: 144
It fails because the result of parsing is not a String, nor Map<String,String> and not even a Map<String,Map<String,String>>. The result object has more complex structure.
If you need to have the object in yuor app for further use, you can create a class(es) to store and Jackson will deserialize it into object.
In case you don't need the whole object, there is readTree method on Jackson library.
It will create JsonNode object you can navigate with your tag names. Something like
res.get("Message").get("Target-key")
(consider properly formed input JSON)
Upvotes: -1