I wanted to add my json response values to an array. My groovy script,
import groovy.json.*
def ResponseMessage = '''{
"Unit": {
"Screen": [{
"Profile ": {
"ID ": 12,
"Rate ": 0
},
"Rate ": 600,
"Primary ": 1,
"Audio ": [{
"Id ": 1,
"Name ": null
}],
"Pre ": 5,
"Post ": 1
}]
}
} '''
def json = new JsonSlurper().parseText(ResponseMessage)
def Screen = json.Unit.Screen
log.info Screen
def array= []
Screen.each { s ->
array.addAll(s.Rate,s.Primary,s.Pre)
log.info "array : " + array
}
Array is returning,
INFO:array : [null, null, null]
Instead of the "create an array, call addAll in a loop" pattern, try this:
def array = Screen.collectMany { s ->
[s.Rate,s.Primary,s.Pre]
}
(Of course, once you've removed the spaces from your JSON keys)
Related
I am trying to map a nested json into a flat file but have an issue referencing between different arrays.
I get it working for each array separately but can't figure out how to properly reference the parent ids to be included. I tried working with indexes and copying the event.id and event.lots.id on the pricings objects but that got really messy.
Maybe I am just on the wrong track or didn't have the right idea on how this might work.
Code
def body = message.getBody(String.class)
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(body)
def i_events = object.events
def i_lots = object.events.lots
def i_pricing = object.events.lots.pricings
def o_values = i_pricing.flatten().collect {"(" + "'" + i_events.collect{it.id}[0] + "'" + "," + "'" + i_lots.collect{it.id}[1] + "'" + "," + "'" + it.id + "'" + "," + "'" +it.name + "'" + ")" }.join(',')
//just using print for testing
println o_values
Result
('event_id1','[id A, id B]','p id1','TEST 1'),('event_id1','[id A, id B]','p id2','TEST 2')
Expected Result
('event_id1','id3','p id1','TEST 1'),('event_id1','id A','p id2','TEST 2')
Sample input
{
"events": [
{
"id": "event_id1",
"name": "Test Event 01",
"to": "2021-08-27T02:30:00.000Z",
"from": "2021-08-26T16:15:00.000Z",
"parkingTo": "2021-08-27T02:30:00.000Z",
"parkingFrom": "2021-08-26T14:15:00.000Z",
"landmarkId": "111",
"slug": "test-event1",
"live": true,
"lots": [
{
"id": "id1",
"name": "Lot 1",
"pricings": []
},
{
"id": "id2",
"name": "Lot 2",
"pricings": []
},
{
"id": "id3",
"name": "Lot3",
"pricings": [
{
"id": "p id1",
"name": "TEST 1"
}
]
}
]
},
{
"id": "event_id2",
"name": "Test Event 2",
"to": "2020-08-31T17:00:00.000Z",
"from": "2020-08-31T14:00:00.000Z",
"parkingTo": "2020-09-01T08:45:00.000Z",
"parkingFrom": "2020-08-31T12:45:00.000Z",
"landmarkId": "111",
"slug": "test-event2",
"live": true,
"lots": [
{
"id": "id A",
"name": "lot A",
"pricings": [
{
"id": "p id2",
"name": "TEST 2"
}
]
},
{
"id": "id B",
"name": "lot B",
"pricings": []
}
]
}
],
"meta": {
"total": 2,
"firstElement": 0,
"lastElement": 2
}
}
Something like this should work (it's hard to say, as your example input seems different to your expected output)
I added a quote method for if the values contain a ', you will need to think if you need this, and how you're going to escape things
def escape(String s) {
"'${s.replaceAll("'", "\\\\'")}'"
}
def output = new JsonSlurper().parseText(body).events.collectMany { event ->
event.lots.collectMany { lot ->
lot.pricings.collect { pricing ->
"(${escape(event.id)}, ${escape(lot.id)}, ${escape(pricing.id)}, ${escape(pricing.name)})"
}
}
}.join(',')
Below is the pojo holding data
class user{
private string userId;
private string role;
private string accessCode;
}
From DB I am getting the below response as one user can have multiple accessCode
"data": [
{
"userId": "userId1",
"role": "admin",
"accesscode": "000008"
},
{
"userId": "userId1",
"role": "admin",
"accesscode": "000007"
},
{
"userId": "userId2",
"role": "analyst",
"accesscode": "000001"
}
]
Expected output as Final Json from rest endpoint
"data": [
{
"userId": "userId1",
"role": "admin",
"accesscode": "000008","000007" // group all access code.
}
{
"userId": "userId2",
"role": "analyst",
"accesscode": "000001"
}
]
What is the best way to achieve this. Any pointers
Here is one way to do it, without using POJOs:
String input = "{" +
" \"data\": [\n" +
" {\n" +
" \"userId\": \"userId1\",\n" +
" \"role\": \"admin\",\n" +
" \"accesscode\": \"000008\"\n" +
" },\n" +
" {\n" +
" \"userId\": \"userId1\",\n" +
" \"role\": \"admin\",\n" +
" \"accesscode\": \"000007\"\n" +
" },\n" +
" {\n" +
" \"userId\": \"userId2\",\n" +
" \"role\": \"analyst\",\n" +
" \"accesscode\": \"000001\"\n" +
" }\n" +
" ]\n" +
"}";
ObjectMapper mapper = new ObjectMapper();
Map<String, List<Map<String, String>>> data = mapper.readValue(input,
new TypeReference<Map<String, List<Map<String, String>>>>() {/**/});
Map<String, List<Map<String, Object>>> combinedData = new HashMap<>();
combinedData.put("data", data.get("data").stream()
.collect(Collectors.groupingBy(
u -> Arrays.asList(u.get("userId"), u.get("role")),
Collectors.mapping(u -> u.get("accesscode"), Collectors.toList())))
.entrySet().stream()
.map(e -> {
Map<String, Object> user = new LinkedHashMap<>();
user.put("userId", e.getKey().get(0));
user.put("role", e.getKey().get(1));
user.put("accesscode", e.getValue());
return user;
})
.collect(Collectors.toList()));
String output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(combinedData);
System.out.println(output);
Output
{
"data" : [ {
"userId" : "userId2",
"role" : "analyst",
"accesscode" : [ "000001" ]
}, {
"userId" : "userId1",
"role" : "admin",
"accesscode" : [ "000008", "000007" ]
} ]
}
I have the json schema:
{
"type ": "record ",
"name ": "JSONSchema",
"namespace ": "com.jsonschema ",
"fields ": [{
"name ": "schema ",
"type ": "string "
},
{
"name ": "body ",
"type ": {
"type ": "record ",
"name ": "BodyFinal ",
"fields ": [{
"name ": "schema ",
"type ": "string "
},
{
"name ": "data ",
"type ": {
"type ": "array ",
"items ": {
"type ": "record ",
"name ": "DataFinal ",
"fields ": [{
"name ": "tna ",
"type ": [
"null ",
"string "
],
"default ": null
},
{
"name ": "aid ",
"type ": [
"null ",
"string "
]
}
]
}
}
}
]
}
}
]
}
How can i generate the case classes automatically using schema as:
case class JSONSchema(schema: String, body: BodyFinal)
case class BodyFinal(schema: String,data: List[DataFinal])
case class DataFinal(tna: Option[String], aid: Option[String])
And then can write a parser to validate the any json received using the case classes. So that if I change the schema in future and add/remove any fields in it then the case classes can be generated and validated against the JSON.
I am new to groovy and trying
1) from the output of prettyPrint(toJson()), I am trying to get a list of values from a specific key inside an json array using groovy. Using the below JSON output from prettyPrint example below, I am trying to create a list which consists only the values of the name key.
My Code:
def string1 = jiraGetIssueTransitions(idOrKey: jira_id)
echo prettyPrint(toJson(string1.data))
def pretty = prettyPrint(toJson(string1.data))
def valid_strings = readJSON text: "${pretty}"
echo "valid_strings.name : ${valid_strings.name}"
Output of prettyPrint(toJson(string1.data))is below JSON:
{
"expand": "places",
"places": [
{
"id": 1,
"name": "Bulbasaur",
"type": {
"grass",
"poison"
}
},
{
"id": 2,
"name": "Ivysaur",
"type": {
"grass",
"poison"
}
}
}
Expected result
valid_strings.name : ["Bulbasaur", "Ivysaur"]
Current output
valid_strings.name : null
The pretty printed JSON content is invalid.
If the JSON is valid, then names can be accessed as follows:
import groovy.json.JsonSlurper
def text = """
{
"expand": "places",
"places": [{
"id": 1,
"name": "Bulbasaur",
"type": [
"grass",
"poison"
]
},
{
"id": 2,
"name": "Ivysaur",
"type": [
"grass",
"poison"
]
}
]
}
"""
def json = new JsonSlurper().parseText(text)
println(json.places*.name)
Basically, use spray the attribute lookup (i.e., *.name) on the appropriate object (i.e., json.places).
I've used something similar to print out elements within the response in ReadyAPI
import groovy.json.*
import groovy.util.*
def json='[
{ "message" : "Success",
"bookings" : [
{ "bookingId" : 60002172,
"bookingDate" : "1900-01-01T00:00:00" },
{ "bookingId" : 59935582,
"bookingDate" : "1900-01-01" },
{ "bookingId" : 53184048,
"bookingDate" : "2019-01-15",
"testId" : "12803798123",
"overallScore" : "PASS" },
{ "bookingId" : 53183765,
"bookingDate" : "2019-01-15T13:45:00" },
{ "bookingId" : 52783312,
"bookingDate" : "1900-01-01" }
]
}
]
def response = context.expand( json )
def parsedjson = new groovy.json.JsonSlurper().parseText(response)
log.info parsedjson
log.info " Count of records returned: " + parsedjson.size()
log.info " List of bookingIDs in this response: " + parsedjson.bookings*.bookingId
I am using google-plus:0.1 plugin in a Grails Application to enable login using Google+ ,I have successfully logged in and I am getting JSON object back.
Inside plugin there is a code where they are turning JSON string to JSON object and returning back to me.
This is the code inside a plugin:-
public Person getCurrentUserProfile() {
Person person
try {
URL url = new URL("https://www.googleapis.com/plus/v1/people/me?access_token=${this.accessToken}")
def jsonString = JSON.parse(url?.text)
println "URL : " + url.toString()
println "JSON : " + jsonString
person = Person.parseJSONForPerson(jsonString)
} catch (GooglePlusException e) {
e.printStackTrace()
}
return person
}
From here I am getting JSON object back
Json string printed in console is:-
URL : https://www.googleapis.com/plus/v1/people/me?access_token=ya29.lgFPSagK5lQ8l19hWuxra8AxsXzZjxlbCetP-aWpUHbq2_djrdvj-3XMFMEgl9r4WfaiLvo7Q3RfJQ
JSON : [etag:"RqKWnRU4WW46-6W3rWhLR9iFZQM/eUT2aym4R39YBu_ra8ZlhztXJ6w", organizations:[[startDate:1995, title:Science, primary:false, name:St.Joseph's Convent, endDate:2008, type:school]], image:[isDefault:false, url:https://lh5.googleusercontent.com/-kuh1_bl_8is/AAAAAAAAAAI/AAAAAAAAADA/ZZfY8ob2QrQ/photo.jpg?sz=50], isPlusUser:true, emails:[[value:kartiki.sahu#crowdera.co, type:account]], kind:plus#person, url:https://plus.google.com/102332421579091283598, id:102332421579091283598, verified:false, name:[familyName:Sahu, givenName:Kartiki], domain:crowdera.co, circledByCount:9, gender:female, displayName:Kartiki Sahu, objectType:person]
I am unable to fetch emails from the object which I am getting.
I tried fetching familyName as
person.name.familyName I got it's value,
but for givenName it is showing null and for emails and organisation it is showiing empty list like [].
My code :-
def code = request.getParameter("code")
String accessToken = accessTokenService.generateAccessToken(code)
googlePlusService.accessToken = accessToken
def person = googlePlusService.getCurrentUserProfile()
Please help.
You can get value like this .
String str="""{
"kind": "plus#person",
"etag": "\\"RqKWnRU4WW46-6W3rWhLR9iFZQM/eUT2aym4R39YBu_ra8ZlhztXJ6w\\"",
"gender": "female",
"emails": [
{
"value": "kartiki.sahu#crowdera.co",
"type": "account"
}
],
"objectType": "person",
"id": "102332421579091283598",
"displayName": "Kartiki Sahu",
"name": {
"familyName": "Sahu",
"givenName": "Kartiki"
},
"url": "https://plus.google.com/102332421579091283598",
"image": {
"url": "https://lh5.googleusercontent.com/-kuh1_bl_8is/AAAAAAAAAAI/AAAAAAAAADA/ZZfY8ob2QrQ/photo.jpg?sz=50",
"isDefault": false
},
"organizations": [
{
"name": "St.Joseph's Convent",
"title": "Science",
"type": "school",
"startDate": "1995",
"endDate": "2008",
"primary": false
}
],
"isPlusUser": true,
"circledByCount": 9,
"verified": false,
"domain": "crowdera.co"
}
"""
def jsonString = new JsonSlurper().parseText(str)
render jsonString.emails.value
}
I am getting output as a following list .
['kartiki.sahu#crowdera.co']
def code = request.getParameter("code")
String accessToken = accessTokenService.generateAccessToken(code)
URL url = new URL("https://www.googleapis.com/plus/v1/people/me?
access_token=${accessToken}")
def jsonString = JSON.parse(url?.text)
println "URL : " + url.toString()
println "JSON : " + jsonString
println "emails "+jsonString.emails.value[0]
println "name "+jsonString.name.givenName + " " +
jsonString.name.familyName