33

I have to create this JSON file in Groovy. I have try many things (JsonOutput.toJson() / JsonSlurper.parseText()) unsuccessfully.

{
   "attachments":[
      {
         "fallback":"New open task [Urgent]: <http://url_to_task|Test out Slack message attachments>",
         "pretext":"New open task [Urgent]: <http://url_to_task|Test out Slack message attachments>",
         "color":"#D00000",
         "fields":[
            {
               "title":"Notes",
               "value":"This is much easier than I thought it would be.",
               "short":false
            }
         ]
      }
   ]
}

This is for posting a Jenkins build message to Slack.

2
  • in title of question you asking about parsing, and in question itself you asking about creating json file. could you please clarify what you want/try to do. Commented Jun 23, 2017 at 10:12
  • @daggett i would like to create those JSON object into a groovy variable. Commented Jun 23, 2017 at 14:38

4 Answers 4

79

JSON is a format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types. So, in general json is a formatted text.

In groovy json object is just a sequence of maps/arrays.

parsing json using JsonSlurperClassic

//use JsonSlurperClassic because it produces HashMap that could be serialized by pipeline
import groovy.json.JsonSlurperClassic

node{
    def json = readFile(file:'message2.json')
    def data = new JsonSlurperClassic().parseText(json)
    echo "color: ${data.attachments[0].color}"
}

parsing json using pipeline

node{
    def data = readJSON file:'message2.json'
    echo "color: ${data.attachments[0].color}"
}

building json from code and write it to file

import groovy.json.JsonOutput
node{
    //to create json declare a sequence of maps/arrays in groovy
    //here is the data according to your sample
    def data = [
        attachments:[
            [
                fallback: "New open task [Urgent]: <http://url_to_task|Test out Slack message attachments>",
                pretext : "New open task [Urgent]: <http://url_to_task|Test out Slack message attachments>",
                color   : "#D00000",
                fields  :[
                    [
                        title: "Notes",
                        value: "This is much easier than I thought it would be.",
                        short: false
                    ]
                ]
            ]
        ]
    ]
    //two alternatives to write

    //native pipeline step:
    writeJSON(file: 'message1.json', json: data)

    //but if writeJSON not supported by your version:
    //convert maps/arrays to json formatted string
    def json = JsonOutput.toJson(data)
    //if you need pretty print (multiline) json
    json = JsonOutput.prettyPrint(json)

    //put string into the file:
    writeFile(file:'message2.json', text: json)

}
Sign up to request clarification or add additional context in comments.

6 Comments

I'm trying to do this. I get "ERROR: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new groovy.json.JsonSlurperClassic" What am I missing?
This doesn't work for me in the latest version of jenkins (2.138.3). I get an issue on the writeJSON step: WriteJSONStep(file: String, json: JSON{}, pretty?: int): java.lang.UnsupportedOperationException: must specify $class with an implementation of interface net.sf.json.JSONMore context here: stackoverflow.com/questions/53337109/…
@DavidGoate, in this case don't use writeFile, but the last three commands in code: JsonOutput.toJson, JsonOutput.prettyPrint, writeFile.
Thank you for the information about JsonSlurperClassic. I tried JsonSlurper, but it causes NotSerializableException if "new" is called more than once, even despite NonCPS annotation.
|
23

Found this question while I was trying to do something (I believed) should be simple to do, but wasn't addressed by the other answer. If you already have the JSON loaded as a string inside a variable, how do you convert it to a native object? Obviously you could do new JsonSlurperClassic().parseText(json) as the other answer suggests, but there is a native way in Jenkins to do this:

node () {
  def myJson = '{"version":"1.0.0"}';
  def myObject = readJSON text: myJson;
  echo myObject.version;
}

Hope this helps someone.

Edit: As explained in the comments "native" isn't quite accurate.

4 Comments

Good call, though this is not quite native, it requires the pipeline utility steps plugin. An excellent plugin to make use of. Full docs here
if we have a string '[ {"version":"1.0.0"} , {"version":"2.0.0"}]' how to read the array ?
You will need Pipeline Utility Steps plugin as mentioned here
this addresses the opposite of the OPs question: how to go from object to json string
2

If you are stucked on an installation using sandboxes and Jenkins Script Security plugin with no possibility to add whitelisted classes/methods, the only way I found is the following :

def slackSendOnRestrictedContext(params) {

    if (params.attachments != null) {
        /* Soooo ugly but no other choice with restrictions of
           Jenkins Script Pipeline Security plugin ^^ */
        def paramsAsJson = JsonOutput.toJson(params)
        def paramsAsJsonFromReadJson = readJSON text: paramsAsJson
        params.attachments = paramsAsJsonFromReadJson.attachments.toString()
    }

    slackSend (params)
}

1 Comment

JsonOutput.toJson( map ) works to me
-1

This will return value of the "version" from the jsonFile file:

def getVersion(jsonFile){

  def fileContent = readFile "${jsonFile}"
  Map jsonContent = (Map) new JsonSlurper().parseText(fileContent)
  version = jsonContent.get("version")

  return version

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.