Falcon
Falcon

Reputation: 442

Class cast Exception during JSON Parsing

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

Answers (3)

Deadron
Deadron

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

Md Shahbaz Ahmad
Md Shahbaz Ahmad

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

Danny Briskin
Danny Briskin

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

Related Questions