Building a json message in groovy using Json builder - json

I am facing a problem in building the json message, i need a json message to be in the below format:
{
success:true,
count:3,
data: [
{id:1, data: SUCCESS},
{id:2, data: FAILURE},
{id:3, data: Not Declared}
]
}
Im anot sure how to do this plz help

You can do it the following way:
class Data { String id; String data }
def yourdata = [
new Data("1","SUCCESS")
new Data("2","FAILURE")
new ...
]
def builder = new groovy.json.JsonBuilder()
def root = builder {
success true
count 3
data yourdata.collect { d ->
["id":d.id,
"data":d.data]
}
}
return builder.toPrettyString()

Related

Parse nested json objects in groovy

I have a json file containing contact info grouped by city. I want to parse the json and create a list of names and numbers but after fiddling for an hour or so, I can't get this to work in groovy.
def ​json = '''{
"date":"2018-01-04T22:01:02.2125",
"boston": [
{
"name":"bob",
"phone":"242 123123",
"ext":"12",
"email":"bob#boston.com"
},
{
"name":"alice",
"phone":"212-123-345",
"ext":"1",
"email":"alice#boston.com"
}
],
"chicago": [
{
"name":"charlie",
"phone":"313-232-545",
"ext":"14",
"email":"charlie#chicago.com"
},
{
"name":"denise",
"phone":"414-123-546",
"ext":"9",
"email":"denise#chicago.com"
}
]
}'''
I have tried a few variations on the following theme but they all failed so far.
parsedjson = slurper.parseText(json)
phonelist = []
parsedjson.each{phonelist.add([it['name'],it['phone']])}
It's tricky with the json you have, as you need to look for the values which are lists... You can do this with a findAll, so given the json:
def ​json = '''{
"date":"2018-01-04T22:01:02.2125",
"boston": [
{
"name":"bob",
"phone":"242 123123",
"ext":"12",
"email":"bob#boston.com"
},
{
"name":"alice",
"phone":"212-123-345",
"ext":"1",
"email":"alice#boston.com"
}
],
"chicago": [
{
"name":"charlie",
"phone":"313-232-545",
"ext":"14",
"email":"charlie#chicago.com"
},
{
"name":"denise",
"phone":"414-123-546",
"ext":"9",
"email":"denise#chicago.com"
}
]
}'''
You can import the JsonSlurper and parse the json as you currently do:
import groovy.json.JsonSlurper
def parsedjson = new JsonSlurper().parseText(json)
Then;
def result = ​parsedjson.findAll { it.value instanceof List } // Find all entries with a list value
.values() // Get all the lists
.flatten() // Merge them into a single list
.collect { [it.name, it.phone] } ​​​​​ // grab the name and phone for each

Unable to split the values in jsonobject in groovy

I'm new to groovy. I'm trying to split the values in json object in groovy but i cant seem to find a solution. Please find the sample code below
def inputFile = new File("C:\\graph.json")
def InputJSON = new JsonSlurper().parseFile(inputFile,'UTF-8')
InputJSON.each{println it}
def names = InputJSON.graph;
def name
for (int kk=0;kk<4;kk++)
{
name=names.JArray1[kk]
run.put(name.runid, name.rundetails);
println "test::"+name.runid+"--------------"+name.rundetails
}
graph.json
{
"graph": {
"JArray1": [
{
"runid": 1,
"rundetails":{
"01_Home":0.231,
"02_Login":0.561}
}
]
}
}
name.rundetails contains the below values
[01_Home:0.231, 02_Login:0.561]
I would like to split and add it as key and value in Hashmap like below format
Key:01_Home Value:0.231
Key:02_Login Value:0.561
How would i do that any advise on this would be helpful. Thanks in advance.
import groovy.json.*
def inputFile = new StringReader('''
{
"graph": {
"JArray1": [{
"runid": 1,
"rundetails": {
"01_Home": 0.231,
"02_Login": 0.561
}
}
]
}
}
''')
def json = new JsonSlurper().parse(inputFile)
json.graph.JArray1.each{run->
println "runid = ${run.runid}"
// at this point `run.rundetails` is a map like you want
println "details = ${run.rundetails}"
}
As I understand you need collection like:
[[Key:01_Home, Value:0.231], [Key:02_Login, Value:0.561]]
Then you may do:
println InputJSON.graph
.JArray1
.rundetails
.collectEntries{it}
.collect{[Key: it.key, Value: it.value]}

Grails GSON JSON views

I want to generate JSON output similar to this one:
var json = {
id: "1",
name: "AAA",
children: [{
id: "2",
name: "BBB",
data: {
relation: "<b>Connections:</b><ul><li> AAA <div>(relation: direct)</div></li><li> CCC <div>(relation: direct)</div></li></ul>"
},
children: [{
id: "3",
name: "CCC",
data: {
relation: "<b>Connections:</b><ul><li> BBB <div>(relation: direct)</div></li></ul>"
},
children: []
}]
}, ....
Here is what I did so far:
grails create-domain-resource json.Object
class Object{
String name
String relation
static hasMany = [children: Object]
public String getData() {
def writer = new StringWriter()
_object.gson
//json g.render(hero)
json {
//data hero.data
data: {relation hero.relation}
name hero.name
}
Problem
I'm not able to produce:
data: {
relation: "<b>Connections:</b><ul><li> BBB <div>(relation: direct)</div></li></ul>"
},
Questions:
1) I've read the official documentation but I'm not able to find how to do transient fields
2) What is best approach of mixing json and xml / html.
3) How to pass json code to another view variable
thank you in advance
You can check the official documentation for gson views at:
http://views.grails.org/latest/#_json_view_api
Domain class
class Object{
String name
String relation
static hasMany = [children: Object]
public String getRelation() {
Template 1 object.gson
import json.Object
model {
Object object
}
json tmpl.object(object)
Template 2 _object.gson
import json.Object
model {
Object object
}
json {
id object.id
data(relation: object.relation)
name object.name
children g.render(object.children,[ excludes:['exclude_fields']])
//children g.render(object.children,[resolveTemplate: false]) // one to many relations - avoid circular error
//object2 object.book.name // one to one relations
}
ObjectController
import grails.plugin.json.view.JsonViewTemplateEngine
import org.springframework.beans.factory.annotation.Autowired
#Autowired
JsonViewTemplateEngine templateEngine
def test() {
def t = templateEngine.resolveTemplate('/object/object')
def writable = t.make(object: Object.get(params.id))
def sw = new StringWriter()
writable.writeTo( sw )
return [json:sw]
}
Questions:
1) I've read the official documentation but I'm not able to find how to do transient fields - you can use Named arguments which are valid values for objects or getters
2) What is best approach of mixing json and xml / html. - **I guess you can check : http://docs.groovy-lang.org/latest/html/gapi/groovy/json/StreamingJsonBuilder.html **
3) How to pass json code to another view variable - **check code above at objectController **

Parse JSON using groovy script (using JsonSlurper)

I am just two days old to groovy, I need to parse a json file with below structure. My actual idea is I need to run a set of jobs in different environments based on different sequences, so I came up with this format of json as a input file to my groovy
{
"services": [{
"UI-Service": [{
"file-location": "/in/my/server/location",
"script-names": "daily-batch,weekly-batch,bi-weekly-batch",
"seq1": "daily-batch,weekly-batch",
"seq2": "daily-batch,weekly-batch,bi-weekly-batch",
"DEST-ENVT_seq1": ["DEV1", "DEV2", "QA1", "QA2"],
"DEST-ENVT_seq2": ["DEV3", "DEV4", "QA3", "QA4"]
}]
}, {
"Mobile-Service": [{
"file-location": "/in/my/server/location",
"script-names": "daily-batch,weekly-batch,bi-weekly-batch",
"seq1": "daily-batch,weekly-batch",
"seq2": "daily-batch,weekly-batch,bi-weekly-batch",
"DEST-ENVT_seq1": ["DEV1", "DEV2", "QA1", "QA2"],
"DEST-ENVT_seq2": ["DEV3", "DEV4", "QA3", "QA4"]
}]
}]
}
I tried below script for parsing the json
def jsonSlurper = new JsonSlurper()
//def reader = new BufferedReader(new InputStreamReader(new FileInputStream("in/my/location/config.json"),"UTF-8"))
//def data = jsonSlurper.parse(reader)
File file = new File("in/my/location/config.json")
def data = jsonSlurper.parse(file)
try{
Map jsonResult = (Map) data;
Map compService = (Map) jsonResult.get("services");
String name = (String) compService.get("UI-Service");
assert name.equals("file-location");
}catch (E){
println Exception
}
I need to first read all the services (UI-service, Mobile-Service, etc..) then their elements and their value
Or you could do something like:
new JsonSlurper().parseText(jsonTxt).services*.each { serviceName, elements ->
println serviceName
elements*.each { name, value ->
println " $name = $value"
}
}
But it depends what you want (and you don't really explain in the question)
Example for reading from JsonParser object:
def data = jsonSlurper.parse(file)
data.services.each{
def serviceName = it.keySet()
println "**** key:${serviceName} ******"
it.each{ k, v ->
println "element name: ${k}, element value: ${v}"
}
}
other options:
println data.services[0].get("UI-Service")["file-location"]
println data.services[1].get("Mobile-Service").seq1

JSON output with Groovy

I have been experimenting with the groovy Jsonbuilder as you can see below trying to look at different ways to build JSON objects and arrays. After things started to make sense, I tried expanding to what is shown below. The question I have is, why does "content" show up in the json pretty string output? I actually have another json object displaying this.class information in json string outputs.
Any ideas? I'm new to this, so it could definitely be an obvious one.
def tt = ["test", "test1"]
def jjj = "jason"
def js3 = new groovy.json.JsonBuilder()
def js2 = new groovy.json.JsonBuilder(tt);
js3 hello: "$jjj", "$jjj": tt
def js4 = new groovy.json.JsonBuilder()
def result = js4([sdn: js3, openflow: js2, type: 3])
println js4.toPrettyString();
outputs:
{
"sdn": {
"content": {
"hello": "jason",
"jason": [
"test",
"test1"
]
}
},
"openflow": {
"content": [
"test",
"test1"
]
},
"type": 3
}
The problem can be restated as...
why does this:
import groovy.json.*
def js3 = new JsonBuilder(["test", "test1"])
def js4 = new JsonBuilder(js3)
println js4.toString()
print:
{"content":["test","test1"]}
and this:
import groovy.json.*
def js3 = new JsonBuilder(["test", "test1"])
def js4 = new JsonBuilder(js3.content)
println js4.toString()
prints this (?) :
["test","test1"]
The short answer is that JsonBuilder has a member named content, which represents the payload. When one JsonBuilder absorbs another, we want to replace the payload, and not nest it. This line is the way to replace the payload:
def js4 = new JsonBuilder(js3.content)
Ultimately, this stems from the fact that JsonBuilder.toString() (code here) calls JsonOutput.toJson(object) (code here).
An exercise for the reader is to experiment with:
class MyBuilder {
def content
}
def myB = new MyBuilder(content: ["test", "test1"])
println JsonOutput.toJson(myB)
println JsonOutput.toJson(myB.content)