JsonSlurper parsing String containing Json into unexpected format - json

From a separate system I get a String parameter "messageJson" whose content is in the form:
{"agent1":"smith","agent2":"brown","agent3":{"agent3_1":"jones","agent3_2":"johnson"}}
To use it in my program I parse it with JsonSlurper.
def myJson = new JsonSlurper().parseText(messageJson)
But the resulting Json has the form:
[agent1:smith, agent2:brown, agent3:[agent3_1:jones, agent3_2:johnson]]
Note the square brackets and the lack of double quotes. How can I parse messageJson so that the original structure is kept?

Ok, thanks to the hint by cfrick, I was able to find a solution. In case anyone else has a similar problem, all I needed to do was using JsonOutput in the end to convert the map back to a Json
I.E. :
def myJson = new JsonSlurper().parseText(messageJson)
myJson << [agent4:"jane"]
def backToJson = JsonOutput.toJson(myJson)

Related

Need help on Groovy Script

I am trying to remove double quotes from the Value of 'version' but, not able to do that with the following groovy codes. Please help me resolving this.
Source JSON:
{"version":"1",
"code":'',
"eccQuoteExternalQuoteId":'100000136',
"reasonForRejection":'',
"rejectionCode":'',
"state":{"code":'SOX_APP',"integrationKey":'Approve'},
"integrationKey":''}
Groovy Script:
def Message processData(Message message) {
//Body
def body = message.getBody(String.class);
def jsonSlurper = new JsonSlurper()
def list = jsonSlurper.parseText(body)
list.each{
it.version=Integer.parseInt(it.get("version").toString().replace(" ",""));
}
def jsonOP = JsonOutput.toJson(list)
message.setBody(jsonOP)
return message;
}
Replace
it.version=Integer.parseInt(it.get("version").toString().replace(" ",""));
with
it.version=it.get("version").toString().toInteger();
see the ref toInteger.
Your json is incorrect because there are single quotes used for some values. However you could try LAX parser to ignore this issue.
def jsonSlurper = new JsonSlurper().setType(JsonParserType.LAX)
If the json from question is coming through the message body then just change
list.each{
it.version=Integer.parseInt(it.get("version").toString().replace(" ",""));
}
To
list.version = list.version as Integer
#daggett is right, you can do like he said.
It seems that the value of that object is a string, not a problem of quotes.
You can check the class of any the object with:
println(it.version.getClass())
if it's a string you can change it in various ways but if its a string you could simply use the below - I'm putting it in more lines just for better visibility but the result is the same as the inline from daggett
def newInt = it.version.toInteger()
it.version = newInt
There are other ways to do the same thing if you really need to convert it.
here a guide:
https://www.baeldung.com/groovy-convert-string-to-integer
Maybe changing the value from string to int in that class creating the JSON is the best way to go.

Groovy: JSON Parsing

Seeing an interesting issue, not sure this is to do with parser or the way it suppose to parse. Any help is appreciated
import groovy.json.JsonSlurper
def dMatch = '''[{"match":{"keyId":"A-102161-application"}},{"match":{"keyId":"A-102162-application"}},{"match":{"keyId":"A-102163-application"}},{"match":{"keyId":"A-102164-application"}},{"match":{"keyId":"A-102165-application"}}]'''
println "T1:: List: " + dMatch
def parser = new JsonSlurper()
def exclude = parser.parseText(dMatch)
println "T2:: Obj: " + exclude.toString()
println "----------------------------------------------------"
Output :
T1:: List: [{"match":{"keyId":"A-102161-application"}},
{"match":{"keyId":"A-102162-application"}},
{"match":{"keyId":"A-102163-application"}},
{"match":{"keyId":"A-102164-application"}},
{"match":{"keyId":"A-102165-application"}}]
T2:: Obj: *[[match:[keyId:A-102161-application]],
[match:[keyId:A-102162-application]],
[match:[keyId:A-102163-application]],
[match:[keyId:A-102164-application]],
[match:[keyId:A-102165-application]]]*
The parsed object supposed to be same as the string but all the values were converted as array list of map.
Any idea why this is generating object like this ? When this is sent to camunda it complains
org.camunda.bpm.engine.ProcessEngineException: Cannot serialize object in variable 'exclude': groovy.json.internal.LazyMap
Use JsonSlurperClassic() - it produces standard HashMap that is serializable.
And if you want to convert object back to json use Json output.toJson(obj)

Cut off the field from JSON string

I have a JSON string like this:
{"id":"111","name":"abc","ids":["740"],"data":"abc"}
I want to cut off the field "ids", however I don't know apriori the values like ["740"]. So, it might be e.g. ["888,222"] or whatever. The goal is to get the json string without the field "ids".
How to do it? Should I use JackMapper?
EDIT:
I tried to use JackMapper as JacksMapper.readValue[Map[String, String]](jsonString)to get only fields that I need. But the problem is that"ids":["740"]` throws the parsing error because it's an array. So, I decided to cut off this field before parsing, though it's an ugly solution and ideally I just want to parse the json string into Map.
Not sure what JackMapper is, but if other libraries are allowed, my personal favourites would be:
Play-JSON:
val jsonString = """{"id":"111","name":"abc","ids":["740"],"data":"abc"}"""
val json = Json.parse(jsonString).as[JsObject]
val newJson = json - "ids"
Circe:
import io.circe.parser._
val jsonString = """{"id":"111","name":"abc","ids":["740"],"data":"abc"}"""
val json = parse(jsonString).right.get.asObject.get // not handling errors
val newJson = json.remove("ids")
Note that this is the minimal example to get you going which doesn't handle bad input etc.

Map to String/String to Map conversion in Groovy

I have a json object that gets passed into a save function as
{
"markings": {
"headMarkings": "Brindle",
"leftForeMarkings": "",
"rightForeMarkings": "sock",
"leftHindMarkings": "sock",
"rightHindMarkings": "",
"otherMarkings": ""
}
** EDIT **
The system parses it and passes it to my function as a mapping. I don't actually have the JSON, although it wouldn't be difficult to build up the JSON myself, it just seems like overkill
* END EDIT **
The toString() function ends up putting the results into the database as
"[rightForeMarkings:, otherMarkings:, leftForeMarkings:sock, leftHindMarkings:sock, rightHindMarkings:, headMarkings:brindle]"
I then want to save that as a string (fairly easy) by calling
params.markings.toString()
From here, I save the info and return the updated information.
My issue is that since I am storing the object in the DB as a string, I can't seem to get the markings back out as a map (to then be converted to JSON).
I have tried a few different things to no avail, although it is completely possible that I went about something incorrectlywith these...
Eval.me(Item.markings)
evaluate(Item.markings)
Item.markings.toList()
Thanks in advance for the help!
Throwing my tests.
Using JSON converters in Grails, I think this should be the approach: (synonymous to #JamesKleeh and #GrailsGuy)
def json = '''{
"markings": {
"headMarkings": "Brindle",
"leftForeMarkings": "",
"rightForeMarkings": "sock",
"leftHindMarkings": "sock",
"rightHindMarkings": "",
"otherMarkings": ""
}
}'''
def jsonObj = grails.converters.JSON.parse(json)
//This is your JSON object that should be passed in to the method
print jsonObj //[markings:[rightForeMarkings:sock, otherMarkings:, leftForeMarkings:, leftHindMarkings:sock, rightHindMarkings:, headMarkings:Brindle]]
def jsonStr = jsonObj.toString()
//This is the string which should be persisted in db
assert jsonStr == '{"markings":{"rightForeMarkings":"sock","otherMarkings":"","leftForeMarkings":"","leftHindMarkings":"sock","rightHindMarkings":"","headMarkings":"Brindle"}}'
//Get back json obj from json str
def getBackJsobObj = grails.converters.JSON.parse(jsonStr)
assert getBackJsobObj.markings.leftHindMarkings == 'sock'
If I understand correctly, you want to convert a String to a JSON object? You can actually bypass converting it to a map, and parse it directly as a JSON object:
import grails.converters.JSON
def json = JSON.parse(Item.markings)
This will give you your entire JSON object, and then you can just reference the values as you would a map.
Edit #2:
So apparently there is no "safe" way to convert that string back to a map without something custom. I would recommend saving the structure in the database as it originally comes in. If you can do that, then all you would need is JSON.parse()

how to create a json enclosed with square brackets in java?

I generate a json with the following code.
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
HashMap<String,String> map = new HashMap<String,String>();
map.put("Message","All");
list.add(map);
Gson gson = new Gson();
String userResponseListValue = gson.toJson(map);
I get the json in the following format
{"Message":"All"}
I need the json to be in the following format
[{"Message":"All"}]
Since I'm new to gson i can't fix this problem. can some one guide me to fix this problem.
Square brackets denote a list or array, so try outputting the list you already prepared but are not using:
gson.toJson(list);
Brackets [] denote an Array in JSON, and what you have is a HashMap, not an Array...
You can manually add the square brackets like:
String userResponseListValue = "[ " + gson.toJson(map) + " ]";
Or create a ArrayList<HashMap>.
EDIT: In fact, you have the Array, but you're not using it! Try:
String userResponseListValue = gson.toJson(list);