0

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

4
  • 1
    Does your input possiblly have quotes around it? It looks like your original input may not be what you expect. Commented Jun 24, 2020 at 17:09
  • The message is JSON {"key":"value"} type. Message is one of the key within this brace.The outer braces are not quotes enclosed in the AWS SQS console. I am using message.getBody() where message is object defined by SQS. Its return type is string. Commented Jun 24, 2020 at 17:55
  • You were right probably. I sneaked into the source to find out the message is like this "Message" : "{\"buildId\":\"B-2020.06.19.00.A........till end, Enclosed and delimited. This is not JSON. Any clue. how to parse this? @Deadron Commented Jun 24, 2020 at 18:26
  • Updated the JSON Commented Jun 24, 2020 at 18:45

3 Answers 3

2

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"));
Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, Previously did not have access to the input. It became obvious after the input. I did not expect this input tbh. Thanks for reminding me to check. Upvoting,Accepting
0

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

1 Comment

XYZ is some integer value. That's why it not enclosed in quotes
-1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.