Groovy. How can I get json elements in array - json

there is such a JSON: https://restcountries.com/v3.1/all
I just want to have a choice "translations" -> "ita" -> "common"
HTTPBuilder getHttpBuilder() {
new HTTPBuilder('https://restcountries.com/')
}
def http = httpBuilder.request(Method.GET, ContentType.JSON){
uri.path = 'v3.1/all'
uri.query = [fields: 'translations,ita,common']
response.success = { resp, json ->
log.error(json.toString()) //string
log.error(JsonOutput.toJson(json).br) //json
log.error(JsonOutput.prettyPrint(JsonOutput.toJson(json))) //formated json
}
}
but I always get either a general view or nothing of what is needed
Help me to understand! Thank you!

Found this solution for me. Maybe someone else will stumble upon it too.
import groovy.json.JsonOutput
import groovyx.net.http.ContentType
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.Method
import groovy.json.JsonSlurper
HTTPBuilder getHttpBuilder() {
new HTTPBuilder('https://restcountries.com/')
}
def http = httpBuilder.request(Method.GET, ContentType.JSON){
uri.path = 'v3.1/all'
}
def tempJson = JsonOutput.toJson(http)
def resultParseJson = parseJsonText(tempJson)
def needResult = resultParseJson.translations.ita.common
def parseJsonText(String textJson){
def jsonSlurper = new JsonSlurper()
return jsonSlurper.parseText(textJson)
}
needResult - what I need.
Perhaps someone will have a more beautiful or correct solution - I will be grateful. But so far this result is satisfactory.

Related

How to parse the json response returned from the HttpBuilder in Groovy?

The following is what GitHub returns from a REST GET method. How to parse it using JSON?
response.success = { resp, reader ->
result = reader.text
}
[{"login":"ghost","id":1,"avatar_url": ....},{"login":"github-enterprise","id":2,"avatar_url": ....}]
You can use awesome tool for working with json - json slurper:
def slurper = new JsonSlurper()
def result = slurper.parseText(result)
def firstLogin = result[0].login
def secondId = result[1].id

Groovy returning JSON

I have the following Groovy script (not a Grails app) that is returning a JSON-like, but it is not strictly valid JSON.
String baseURL = 'https://test.com'
File userFile = new File("./user.json")
def client = new HTTPBuilder(baseUrl)
client.headers['Content-Type'] = 'application/json'
client.request(GET, JSON) { req ->
requestContentType = JSON
headers.Accept = 'application/json'
response.success = { resp, json ->
userFile.append json.toString()
println JsonOutput.toJson(json.toString())
}
}
I am trying to create a JSON output file. I have tried using JsonOutput.prettyPrint and I looked at JsonBuilder, but that looks like I would have to build the JSON structure manually when Groovy should support the output. This is what I am getting back.
{AssetNumber=AssetNumber1, DeviceFriendlyName=FriendlyName1, PhoneNumber=17035551231, SerialNumber=SerialNumber1, Udid=Udid1, UserEmailAddress=user1#email.com, UserId=userId1, UserName=userName1}
As I said, this is JSON-like, but not strictly valid. I was expecting something like:
{"AssetNumber": "AssetNumber1", "DeviceFriendlyName": "FriendlyName1"....}
Any ideas?
It works perfectly fine (groovy v 2.3.6):
import groovy.json.*
def pretty = JsonOutput.prettyPrint(JsonOutput.toJson([1:2]))
assert pretty == """{
"1": 2
}"""
In this closure:
response.success = { resp, json ->
userFile.append json.toString()
println JsonOutput.toJson(json.toString())
}
You're getting an instance of Map under json variable. You do not need to turn it into a string. Instead use:
userFile.append JsonOutput.toJson(json)
println JsonOutput.toJson(json)

"Failed to invoke public scala.collection.immutable.List() with no args" using GSON

First off here's my code:
// Description.scala
package com.wausoft.jsonrpc.model
import com.google.gson.annotations.SerializedName
class Description {
#SerializedName("Language")
var language = ""
#SerializedName("Description")
var description = ""
}
// Item.scala
package com.wausoft.jsonrpc.model
import com.google.gson.annotations.SerializedName
class Item {
#SerializedName("Number")
var number = 0
#SerializedName("Description")
var description: List[Description] = Nil
}
// Result.scala
package com.wausoft.jsonrpc.model
import com.google.gson.annotations.SerializedName
class Result {
#SerializedName("Type")
var typeNum = 0
#SerializedName("Description")
var description: List[Description] = Nil
#SerializedName("Items")
var items: List[Item] = Nil
}
// Response.scala
package com.wausoft.jsonrpc.model
class Response {
var jsonRPC = ""
var result: List[Result] = Nil
var id = 0
}
// main file
package com.wausoft.jsonrpc
import scala.io.Source
import com.wausoft.jsonrpc.model._
import com.google.gson._
object Program {
def getJson(file: String): String = Source.fromFile(file)("UTF-8").mkString
def parseJFile(json: String): Response = new Gson().fromJson(json, classOf[Response])
// insert main method here
}
I get the error in the title when I try to parse the data to a POSO, it works fine if I replace all of the lists with arrays, but the thing that bothers me is that this works:
var lst: List[Int] = Nil
lst = List(1,2,3,4,5)
lst foreach print // produces 12345
If the above example works, why doesn't my code? I mean I'm basically doing the exact same, with the only exception that I let Gson handle the list making, is it because it's wrapped in a class, or did I miss something?
See How can I use Gson in Scala to serialize a List?.
Quote from the question: "Gson doesn't know about Scala's collection classes". This answer shows how to serialize a class with a Scala List member to JSON using GSON. The former is the source of the problem, the later is the solution.

Parse rest api content

My rest API returns something like:
{"UserInfo":[{"userName":"zbradford","firstName":"Zoe","lastName":"Bradford","emailAddress":"ZBradford#ABC.COM"}]}
I would like to let it return only the email address value: ZBradford#ABC.COM
Here is my code:
import groovy.json.JsonSlurper;
def slurper = new JsonSlurper()
def jsonResponse = slurper.parseText(resp)
jsonResponse.UserInfo.emailAddress.join(',')
I got a java null error, any suggestion on my code? Thanks
Has to be a json string to parse.
import groovy.json.JsonSlurper
def str = '{"UserInfo":[{"userName":"zbradford","firstName":"Zoe",
"lastName":"Bradford","emailAddress":"ZBradford#ABC.COM"}]}'
def slurper = new JsonSlurper().parseText(str)
assert slurper.UserInfo[0].emailAddress == 'ZBradford#ABC.COM'
Have a look here.

Posting JSON data with Groovy's HTTPBuilder

I've found this doc on how to post JSON data using HttpBuilder. I'm new to this, but it is very straightforward example and easy to follow. Here is the code, assuming I had imported all required dependencies.
def http = new HTTPBuilder( 'http://example.com/handler.php' )
http.request( POST, JSON ) { req ->
body = [name:'bob', title:'construction worker']
response.success = { resp, json ->
// response handling here
}
}
Now my problem is, I'm getting an exception of
java.lang.NullPointerException
at groovyx.net.http.HTTPBuilder$RequestConfigDelegate.setBody(HTTPBuilder.java:1131)
Did I miss something? I'll greatly appreciate any help you can do.
I took a look at HttpBuilder.java:1131, and I'm guessing that the content type encoder that it retrieves in that method is null.
Most of the POST examples here set the requestContentType property in the builder, which is what it looks like the code is using to get that encoder. Try setting it like this:
import groovyx.net.http.ContentType
http.request(POST) {
uri.path = 'http://example.com/handler.php'
body = [name: 'bob', title: 'construction worker']
requestContentType = ContentType.JSON
response.success = { resp ->
println "Success! ${resp.status}"
}
response.failure = { resp ->
println "Request failed with status ${resp.status}"
}
}
I had the same problem a while ago and found a blog that noted the 'requestContentType' should be set before 'body'. Since then, I've added the comment 'Set ConentType before body or risk null pointer' in each of my httpBuilder methods.
Here's the change I would suggest for your code:
import groovyx.net.http.ContentType
http.request(POST) {
uri.path = 'http://example.com/handler.php'
// Note: Set ConentType before body or risk null pointer.
requestContentType = ContentType.JSON
body = [name: 'bob', title: 'construction worker']
response.success = { resp ->
println "Success! ${resp.status}"
}
response.failure = { resp ->
println "Request failed with status ${resp.status}"
}
}
Cheers!
If you need to execute a POST with contentType JSON and pass a complex json data, try to convert your body manually:
def attributes = [a:[b:[c:[]]], d:[]] //Complex structure
def http = new HTTPBuilder("your-url")
http.auth.basic('user', 'pass') // Optional
http.request (POST, ContentType.JSON) { req ->
uri.path = path
body = (attributes as JSON).toString()
response.success = { resp, json -> }
response.failure = { resp, json -> }
}
I found an answer in this post: POST with HTTPBuilder -> NullPointerException?
It's not the accepted answer, but it worked for me. You may need to set the content type before you specify the 'body' attribute. It seems silly to me, but there it is. You could also use the 'send contentType, [attrs]' syntax, but I found it more difficult to unit test. Hope this helps (late as it is)!
I gave up on HTTPBuilder in my Grails application (for POST at least) and used the sendHttps method offered here.
(Bear in mind that if you are using straight Groovy outside of a Grails app, the techniques for de/encoding the JSON will be different to those below)
Just replace the content-type with application/json in the following lines of sendHttps()
httpPost.setHeader("Content-Type", "text/xml")
...
reqEntity.setContentType("text/xml")
You will also be responsible for marshalling your JSON data
import grails.converters.*
def uploadContact(Contact contact){
def packet = [
person : [
first_name: contact.firstName,
last_name: contact.lastName,
email: contact.email,
company_name: contact.company
]
] as JSON //encode as JSON
def response = sendHttps(SOME_URL, packet.toString())
def json = JSON.parse(response) //decode response
// do something with json
}