2

I read this and several other postings on SO and elsewhere about how to send a Post call via HttpBuilder with JSON as the data content. My problem is that NONE OF THOSE SOLUTIONS are working!

My problem is only slightly different. I have existing JSON data in a file. When I attempt to send this to the REST interface with curl:

curl -X POST -u "username:password" -d @/path/to/myFile.json http://localhost:8080/path/here --header "Content-Type:application/json"

all works perfectly well. Here is where I am at (some extra code IS in there, read on):

def myFile = new File('/path/to/myFile.json')
if (!myFile.exists()) println "ERROR!  Do not have JSON file!"

def convertedText = myFile.text.replaceAll('\\{', '[')
convertedText = convertedText.replaceAll('\\}', ']') 

def jsonBldr = new JsonBuilder()
jsonBldr myFile.text

println jsonBldr.toString()

def myClient = new groovyx.net.http.HTTPBuilder('http://username:password@localhost:8080/my/path')
myClient.setHeaders(Accept: 'application/json')

results = myClient.request(POST, JSON) { req ->
    body = [ jsonBldr.toString() ]
    requestContentType = JSON
    response.success = { resp, reader ->
        println "SUCCESS! ${resp.statusLine}"
    }

    response.failure = { resp ->
        println "FAILURE! ${resp.properties}"
    }
}

This results in the 'failure' closure with this data:

statusLine:HTTP/1.1 400 Exception evaluating property 'id' for java.util.ArrayList, Reason: groovy.lang.MissingPropertyException: No such property: id for class: java.lang.String

FWIW, there is no "id" in my JSON anywhere. If I change the "body" line from "[ jsonBldr.toString() ]" to "[ convertedText ]" - which is why that code is up there, I get the same error. If I take out the brackets on the body, I get an error stating that the body is not data for an array (as its a Map).

Can anyone (far groovier than I) tell me what the %%$#@ I am doing wrong???

Community
  • 1
  • 1
JoeG
  • 7,191
  • 10
  • 60
  • 105

1 Answers1

4

You need JsonSlurper instead of JsonBuilder. After which the implementation would look like:

def myFile = new File('/path/to/myFile.json')
if (!myFile.exists()) println "ERROR!  Do not have JSON file!"

def bodyMap = new JsonSlurper().parseText(myFile.text)

def myClient = new groovyx.net.http.HTTPBuilder('http://username:password@localhost:8080/my/path')
modelClient.setHeaders(Accept: 'application/json')

results = myClient.request(POST, JSON) { req ->
    requestContentType = JSON
    body = bodyMap
    response.success = { resp, reader ->
        println "SUCCESS! ${resp.statusLine}"
    }

    response.failure = { resp ->
        println "FAILURE! ${resp.properties}"
    }
}

However, I am not clear what is difference between myFile and modelFile in your code.

dmahapatro
  • 49,365
  • 7
  • 88
  • 117
  • THANK YOU!!! Don't know why, but I had to change 'requestContextType' from JSON to 'URLENC', but now it works! – JoeG Aug 08 '13 at 10:51
  • 2
    Separately, the doc (http://groovy.codehaus.org/gapi/index.html?groovy/json/JsonBuilder.html) for the JsonBuilder.toString method reads: "Serializes the internal data structure built with the builder to a conformant JSON payload string", so while I really like groovy, I still feel like I am on the outside trying to get in! In other words, given this doc, how was I supposed to know and/or find out how to make this work? Sorry - off topic, just needed to rant! – JoeG Aug 08 '13 at 10:53
  • @joeg it was kind of self explanatory. We are not "building" a json but reading one (slurper). You will get into it in time for sure. :) – dmahapatro Aug 08 '13 at 11:54
  • 2
    @JoeG Also the body never excepts a string. have a look at [POST using JSON](http://groovy.codehaus.org/modules/http-builder/doc/json.html) and the API for [JsonGroovyBuilder](http://json-lib.sourceforge.net/apidocs/net/sf/json/groovy/JsonGroovyBuilder.html) which is used by HttpBuilder. I hope this would clear up the grey area. :) – dmahapatro Aug 08 '13 at 13:19
  • While I had read/skimmed that page before, I missed that (now obvious) detail. That helps a lot too - thanks! – JoeG Aug 08 '13 at 13:44
  • @dmahapatro is there a way to read the response's body rather than the statusLine? – kgui Aug 14 '17 at 14:41
  • @Crt Did you try using `reader.text()`? reader should have the response body. – dmahapatro Aug 15 '17 at 20:34